【二維前綴和】小白月賽-祕法地震

引言:
矩陣前綴和
矩陣前綴和,即一個矩陣的一片區域的和,如圖:
在這裏插入圖片描述
基本公式就是:pre[i][j]=pre[i-1][j]+pre[i][j-1]-pre[i-1][j-1]+a[i][j];

題目:
祕法地震
鏈接:https://ac.nowcoder.com/acm/contest/2272/C
來源:牛客網

題目描述
帕秋莉掌握了一種土屬性魔法

這種魔法可以在一片k×k大小的一個正方形區域內產生地震

但是如果某片即將產生地震的區域內有建築物,帕秋莉會停止施法

整個地圖大小爲n×m,其中一些地方有建築

請問有多少種可能的情況,使得帕秋莉會停止施法

輸入描述:
第一行三個數n, m, k,意義見描述
接下來一個n×m的01矩陣表示這篇區域的情況,1表示這個地方有建築
輸出描述:
輸出一個數表示答案
示例1
輸入
複製
4 4 2
1000
0100
0000
0001
輸出
複製
5
備註:
對於30%的數據,n, m≤30
對於100%的數據,n, m≤1000,k≤min(n, m)

思路:
求出矩陣的前綴和,然後對於每個i<=n-k+1,j<=m-k+1區間內的點(i,j),判斷它的右下方的k*k區域的前綴和是否大於1,若是的話,說明包含了建築物。(跟暴力的思路是一樣的,只是少了兩層循環~~~~)
對於每個點的k*k區域求法是這樣的:

int judge(int x,int y){
	int ex=x+k-1;
	int ey=y+k-1;
	return pre[ex][ey]-pre[x-1][ey]-pre[ex][y-1]+pre[x-1][y-1];
}

其實不難理解,就是將上面通式中的a[i][j]換成了一個大的k*k矩陣。
完整代碼:

#include<bits/stdc++.h>
using namespace std;
template<class T>inline void read(T &res)
{
	char c;T flag=1;
	while((c=getchar())<'0'||c>'9')if(c=='-')flag=-1;res=c-'0';
	while((c=getchar())>='0'&&c<='9')res=res*10+c-'0';res*=flag;
}

const int maxn=3005;
char b[maxn][maxn];
int a[maxn][maxn],pre[maxn][maxn];
int n,m,k,sum=0;

int judge(int x,int y){
	int ex=x+k-1;
	int ey=y+k-1;
	return pre[ex][ey]-pre[x-1][ey]-pre[ex][y-1]+pre[x-1][y-1];
}

int main(){
	read(n);
	read(m);
	read(k);
	for(int i=1;i<=n;i++){
		for(int j=1;j<=m;j++){
			scanf("%c",&b[i][j]);
		}
		getchar();
	}
	for(int i=1;i<=n;i++){
		for(int j=1;j<=m;j++){
			a[i][j]=b[i][j]-'0';
		}
	}
	for(int i=1;i<=n;i++){
		for(int j=1;j<=m;j++){
			pre[i][j]=pre[i-1][j]+pre[i][j-1]-pre[i-1][j-1]+a[i][j];
		}
	}
	for(int i=1;i<=n-k+1;i++){
		for(int j=1;j<=m-k+1;j++){
			if(judge(i,j)){
				sum++;
			}
		}
	}
	printf("%d\n",sum);
	return 0;
}
發佈了57 篇原創文章 · 獲贊 84 · 訪問量 1萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章