您的位置:首页 > 其它

【NOIP模拟】矩阵

2016-09-22 16:35 197 查看

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);
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: