您的位置:首页 > 其它

Codeforces 611C New Year and Domino(二维前缀和)

2016-07-24 10:00 483 查看
题目大概说给一个n*m个格子,格子'.'表示可以放东西,多次询问矩形区域(x1,y1)-(x2,y2)有几种放一张1*2的骨牌的方案数。

分别考虑横着竖着放,预处理出二维的前缀和,即sum[x][y]表示(1,1)-(x,y)的横着或者竖着放的方案数,然后对于每一个询问就拆成几个前缀和容斥一下。。

细节要注意。。骨牌是1*2的。。

#include<cstdio>
#include<cstring>
using namespace std;
char map[555][555];
int hsum[555][555],vsum[555][555];
int main(){
int n,m;
scanf("%d%d",&n,&m);
for(int i=1; i<=n; ++i){
for(int j=1; j<=m; ++j){
scanf(" %c",&map[i][j]);
}
}

for(int i=1; i<=n; ++i){
for(int j=2; j<=m; ++j){
int t=(map[i][j]=='.' && map[i][j-1]=='.');
if(i==0){
hsum[i][j]=hsum[i][j-1]+t;
}else{
hsum[i][j]=hsum[i][j-1]+hsum[i-1][j]-hsum[i-1][j-1]+t;
}
}
}
for(int i=2; i<=n; ++i){
for(int j=1; j<=m; ++j){
int t=(map[i][j]=='.' && map[i-1][j]=='.');
if(j==0){
vsum[i][j]=vsum[i-1][j]+t;
}else{
vsum[i][j]=vsum[i][j-1]+vsum[i-1][j]-vsum[i-1][j-1]+t;
}
}
}

int q,x1,y1,x2,y2;
scanf("%d",&q);
while(q--){
scanf("%d%d%d%d",&x1,&y1,&x2,&y2);
int res=hsum[x2][y2]-hsum[x2][y1]-hsum[x1-1][y2]+hsum[x1-1][y1];
res+=vsum[x2][y2]-vsum[x2][y1-1]-vsum[x1][y2]+vsum[x1][y1-1];
printf("%d\n",res);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: