【NOIP模拟】矩阵

来源:互联网 发布:笨驴软件 编辑:程序博客网 时间:2024/06/06 08:29

Description

在麦克雷的面前出现了一个有n*m个格子的矩阵,每个格子用“.”或“#”表示,“.”表示这个格子可以放东西,“#”则表示这个格子不能放东西。现在他拿着一条1*2大小的木棒,好奇的他想知道对于一些子矩阵,有多少种放木棒的方案。

Solution

这是一道水的不行的题,每次找点对个数除以2就好了。
矩阵前缀和不水?

Code

#include<iostream>#include<cstdio>#include<cmath>#include<algorithm>#include<cstring>#define fo(i,a,b) for(i=a;i<=b;i++)using namespace std;const int maxn=507;int i,j,k,l,t,n,m,ans;char s[maxn][maxn];int a[maxn][maxn],shang[maxn][maxn],xia[maxn][maxn],zuo[maxn][maxn],you[maxn][maxn];int b[maxn][maxn],x,y,cas,xx,yy,f[maxn][maxn];int fang[4][2]={1,0,0,1,-1,0,0,-1};int main(){//  freopen("fan.in","r",stdin);//  freopen("fan.out","w",stdout);    scanf("%d%d",&n,&m);    fo(i,1,n){        scanf("%s",s[i]+1);        fo(j,1,m){            if(s[i][j]=='.')b[i][j]=1;        }    }    fo(i,1,n){        fo(j,1,m){            if(!b[i][j])continue;            fo(k,0,3){                x=fang[k][0]+i,y=fang[k][1]+j;                if(x<1||x>n||y<1||y>m||b[x][y]==0)continue;                a[i][j]++;                if(k==0)xia[i][j]++;                else if(k==1)you[i][j]++;                else if(k==2)shang[i][j]++;                else zuo[i][j]++;            }        }    }    fo(i,1,n){        fo(j,1,m){            f[i][j]+=f[i-1][j]+f[i][j-1]-f[i-1][j-1]+a[i][j];            shang[i][j]+=shang[i][j-1];            xia[i][j]+=xia[i][j-1];            zuo[i][j]+=zuo[i-1][j];            you[i][j]+=you[i-1][j];        }    }    for(scanf("%d",&cas);cas;cas--){        scanf("%d%d%d%d",&x,&y,&xx,&yy);        ans=0;        ans-=(zuo[xx][y]-zuo[x-1][y])+(you[xx][yy]-you[x-1][yy])        +(shang[x][yy]-shang[x][y-1])+(xia[xx][yy]-xia[xx][y-1]);        ans=(ans+f[xx][yy]-f[x-1][yy]-f[xx][y-1]+f[x-1][y-1])/2;        printf("%d\n",ans);    }}
2 0