这道题有点味道,类似二维前缀和的思想,我们发现行列可以分开求互不影响,所以考虑两个数组代表行列,然后分别求二维前缀,用二维前缀和的方式来求取前面矩阵的里面的行或列的总数
再询问的时候,用类似二维前缀和的方式求取,但是这里的公式与普通二维前缀和不一样。因为我们这个是满足条件的情况
所以如果是边界与边界之外的相连,那是不算的,所以计算的时候要小心,行列的计算方法也不一样,比如对于行来说,矩阵上表面是没关系的,但是左表面却是有关系的,仔细想想就能发现。
#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]); } }