您的位置:首页 > 其它

Codeforces 611C

2016-01-07 20:19 183 查看
题目链接:http://codeforces.com/problemset/problem/611/C

C:

一个矩阵(500*500),有些障碍点和空格点。

现在可以放一种1*2的骨牌,骨牌只能放在空格点。

问对于(x1,y1,x2,y2)这个矩阵,有多少种合法的放骨牌的方式。

很明显的dp[x2][y2] + dp[x1][y1] - dp[x2][y1] - dp[x1][y2]的模式,因为骨牌横竖放置的不一样所以稍微调一下下标就可以。

一.

刚开始想的时候想一下子把二维的答案直接存下来,但显然这样子是没法递推的,所以只能横着算一遍纵着算一遍,不过就是这样相比一维的话,记录的是以i,j为右下角的横或纵的数量,也就是说表示的是一个矩形的,而一维的话表示的是一行或者一列的,所以说只需要在处理的时候,把横或者纵的那条边去掉就可以了,不要多减就可以了!!!

二.用一维前缀和优化的时候,居然卡在了一个坑上,即sum[x2]-sum[x1],而不是x1-1,太坑了,这bug很是不好找啊!!!

[code]#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=5e2+10;
char a[maxn][maxn];
int n,m;
int sumrow[maxn][maxn],sumcol[maxn][maxn];
int main(){
    cin>>n>>m;
    for(int i=1;i<=n;i++){
        scanf("%s",a[i]+1);
    }
    for(int i=1;i<=n;i++){
        for(int j=1;j<=m;j++){
            if(a[i][j]=='.'&&a[i][j-1]=='.'){
                sumrow[i][j]=sumrow[i][j-1]+1;
            }
            else sumrow[i][j]=sumrow[i][j-1];
        }
    }
    for(int j=1;j<=m;j++){
        for(int i=1;i<=n;i++){
            if(a[i][j]=='.'&&a[i-1][j]=='.'){
                sumcol[i][j]=sumcol[i-1][j]+1;
            }
            else sumcol[i][j]=sumcol[i-1][j];
        }
    }
    int q,x1,y1,x2,y2;scanf("%d",&q);
    while(q--){
        int sum=0;
        scanf("%d%d%d%d",&x1,&y1,&x2,&y2);
        for(int i=x1;i<=x2;i++){
            sum+=sumrow[i][y2]-sumrow[i][y1];
        }
        for(int i=y1;i<=y2;i++){
            sum+=sumcol[x2][i]-sumcol[x1][i];
        }
        printf("%d\n",sum);
    }
    return 0;
}


二维的代码:

[code]
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=5e2+10;
char a[maxn][maxn];
int n,m;
int sumrow[maxn][maxn],sumcol[maxn][maxn];
int main(){
    cin>>n>>m;
    for(int i=1;i<=n;i++){
        scanf("%s",a[i]+1);
    }
    for(int i=1;i<=n;i++){
        for(int j=1;j<=m;j++){
            sumrow[i][j]=sumrow[i][j-1]+sumrow[i-1][j]-sumrow[i-1][j-1];
            sumcol[i][j]=sumcol[i][j-1]+sumcol[i-1][j]-sumcol[i-1][j-1];
            if(a[i][j]=='.'&&a[i][j-1]=='.') sumrow[i][j]++;
            if(a[i][j]=='.'&&a[i-1][j]=='.') sumcol[i][j]++;
        }
    }

    int q,x1,y1,x2,y2;scanf("%d",&q);
    while(q--){
        int sum=0;
        scanf("%d%d%d%d",&x1,&y1,&x2,&y2);
        sum+=sumrow[x2][y2]-sumrow[x1-1][y2]-sumrow[x2][y1]+sumrow[x1-1][y1];
        sum+=sumcol[x2][y2]-sumcol[x1][y2]-sumcol[x2][y1-1]+sumcol[x1][y1-1];
        printf("%d\n",sum);
    }
    return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: