【NOIP模拟】矩阵

Description

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

Solution

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

Code

#include
#include
#include
#include
#include
#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);
    }
}

你可能感兴趣的:(noip,贪心)