CF611C New Year and Domino

这道题有点味道,类似二维前缀和的思想,我们发现行列可以分开求互不影响,所以考虑两个数组代表行列,然后分别求二维前缀,用二维前缀和的方式来求取前面矩阵的里面的行或列的总数

再询问的时候,用类似二维前缀和的方式求取,但是这里的公式与普通二维前缀和不一样。因为我们这个是满足条件的情况

所以如果是边界与边界之外的相连,那是不算的,所以计算的时候要小心,行列的计算方法也不一样,比如对于行来说,矩阵上表面是没关系的,但是左表面却是有关系的,仔细想想就能发现。

#include<iostream>
#include<cstring>
#include<cstdio>
#include<map>
#include<algorithm>
#define ull unsigned long long
using namespace std;
typedef long long ll;
const int N=1e5+10;
int a[600][600];
int b[600][600];
char  s[600][600];
int main(){
    int n,m;
    cin>>n>>m;
    int i;
    for(i=1;i<=n;i++){
        scanf("%s",s[i]+1);
    }
    int j;
    for(i=1;i<=n;i++){
        for(j=1;j<=m;j++){
            if(s[i][j]=='.'&&s[i-1][j]=='.')
                a[i][j]++;
            if(s[i][j]=='.'&&s[i][j-1]=='.')
                b[i][j]++;
            a[i][j]+=(a[i-1][j]+a[i][j-1]-a[i-1][j-1]);
            b[i][j]+=(b[i-1][j]+b[i][j-1]-b[i-1][j-1]);
        }
    }
    int q;
    cin>>q;
    while(q--){
        int l1,r1,l2,r2;
        scanf("%d%d%d%d",&l1,&r1,&l2,&r2);
        printf("%d\n",a[l2][r2]-a[l1][r2]-a[l2][r1-1]+a[l1][r1-1]+b[l2][r2]-b[l2][r1]-b[l1-1][r2]+b[l1-1][r1]);
    }

}
View Code

 

posted @ 2020-03-31 16:13  朝暮不思  阅读(139)  评论(0编辑  收藏  举报