题意:输入h,w表示行和列的数目,接下来h行描述一个网格,每一行有一个长度为w的字符串,每个字符要么是'.',要么是'#',分别表示空的和禁止的。
输入一个q,接下来得q行有4个数,表示一个小网格的左上角的横纵坐标和右下角的横纵坐标。
输出每个小方格内有几个2个连在一起的空格。
思路:网格存在gg[MAXN][MAXN]中,用两个二位数组row[MAXN][MAXN]和column[MAXN][MAXN];row[i][j]表示第i行从开始到j这个位置有几个2个连在一起的空格,column[i][j]表示第j列从开始到i这个位置有几个2个连在一起的空格。
row举例来说,如果gg[i][j]这个位置是'.'并且它前面gg[i][j-1]这个位置也是'.'的话row[i][j]=row[i][j-1]+1;否则的话,row[i][j]=row[i][j-1]。
要注意越界的问题。
if(gg[i][j]=='.'&&j>1&&gg[i][j-1]=='.') row[i][j]=row[i][j-1]+1;
else row[i][j]=row[i][j-1];
if(gg[i][j]=='.'&&i>1&&gg[i-1][j]=='.') column[i][j]=column[i-1][j]+1;
else column[i][j]=column[i-1][j];
#include<iostream> #include<cstdio> #include<cstring> using namespace std; char gg[510][510]; int row[510][510],column[510][510]; int x1[100010],y1[100010],x2[100010],y2[100010]; int main() { int h,w,q; scanf("%d %d",&h,&w); getchar(); memset(row,0,sizeof(row)); memset(column,0,sizeof(column)); int i,j; for(i=1; i<=h; i++) { for(j=1; j<=w; j++) { scanf("%c",&gg[i][j]); if(gg[i][j]=='.'&&j>1&&gg[i][j-1]=='.') row[i][j]=row[i][j-1]+1; else row[i][j]=row[i][j-1]; if(gg[i][j]=='.'&&i>1&&gg[i-1][j]=='.') column[i][j]=column[i-1][j]+1; else column[i][j]=column[i-1][j]; } getchar(); } /* for(i=1; i<=h; i++) { for(j=1; j<=w; j++) cout<<row[i][j]<<" "; cout<<endl; } cout<<endl<<endl; for(i=1; i<=h; i++) { for(j=1; j<=w; j++) cout<<column[i][j]<<" "; cout<<endl; } */ scanf("%d",&q); for(i=0; i<q; i++) scanf("%d%d%d%d",&x1[i],&y1[i],&x2[i],&y2[i]); __int64 ans; for(i=0; i<q; i++) { ans=0; for(j=x1[i]; j<=x2[i]; j++) { //cout<<row[j][y2[i]]<<" "<<row[j][y1[i]]<<endl; ans+=row[j][y2[i]]-row[j][y1[i]]; } for(j=y1[i]; j<=y2[i]; j++) { //cout<<column[x2[i]][j]<<" "<<column[x1[i]][j]<<endl; ans+=column[x2[i]][j]-column[x1[i]][j]; } cout<<ans<<endl; } return 0; }