Codeforces 1200D White Lines 二维差分

题目链接:https://www.luogu.org/problem/CF1200D

题意:

分析:对每行每列单独进行分析,以行举例

对于每一行,找出最左边的黑点和最右边的黑点(可能为一个),如果不存在就先将答案+1,并跳过该行

如果两点长度大于K,则不可能有矩形满足将该行变为全白行,跳过该行

如果小于k的话,说明存在点能够将该行变为全白行,设该行为第i行的话,左右黑点纵坐标分别为l,r,我们发现坐标范围在(i-k+1,r-k+1)~(i,l)之间的点都可以将该行变为全白行

我们可以考虑用一个二维的差分数组来记录变化,diff[i][j]表示从(0,0)到(i,j)的变化值

那显然我们可以将diff[i][l]++,diff[i-k][l]--,diff[i][r-k]--,在将被多减了一次的diff[i-k][r-k]+1,然后从点(n,n)开始,向前递推,求出每个点可以变白行的值

令x=rk+1,y=l,递推式即为:pra[i][j]=pra[i+1][j]+pra[i][j+1]pra[i+1][j+1]+sum[i][j]

代码实现过程要注意数组越界情况

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int inf=0x3f3f3f3f;
#define mem0(a) memset(a,0,sizeof(a))
#define meminf(a) memset(a,0x3f,sizeof(a))
#define ls rt<<1
#define rs rt<<1|1
typedef unsigned long long ull;
const int maxn=150010;
const int mod=1e9+7;
char a[2010][2010];
int diff[2010][2010];
int pre[2010][2010];
int main(){
    int n,k;scanf("%d%d",&n,&k);
    for(int i=1;i<=n;i++){
        scanf("%s",a[i]+1);
    }
    //line operation
    int ans=0;
    for(int i=1;i<=n;i++){
        int l=n+1,r=0;
        for(int j=1;j<=n;j++){
            if(a[i][j]=='B'){
                l=min(l,j);
                r=max(r,j);
            }
        }
        if(l==n+1) {
            ans++;continue;
        }
        if(r-l>=k)continue;
        int x=max(1,r-k+1),y=l;//可行区域的左右边界 
        diff[i][y]++;diff[i][x-1]--;
        if(i>=k)diff[i-k][y]--,diff[i-k][x-1]++;
    }
    //row operation
    for(int i=1;i<=n;i++){
        int u=n+1,d=0;
        for(int j=1;j<=n;j++){
            if(a[j][i]=='B'){
                u=min(u,j);
                d=max(d,j);
            }
        }
        if(u==n+1){
            ans++;continue;
        }
        if(d-u>=k)continue;
        int x=max(1,d-k+1),y=u;//可行区域的上下边界
        diff[y][i]++; diff[x-1][i]--;
        if(i>=k)diff[y][i-k]--,diff[x-1][i-k]++;
    }
    int res=0;
    for(int i=n;i>=1;i--){
        for(int j=n;j>=1;j--){
            pre[i][j]=pre[i+1][j]+pre[i][j+1]-pre[i+1][j+1]+diff[i][j];
            res=max(res,pre[i][j]);
        }
    }
    printf("%d
",ans+res);
    return 0;
}
原文地址:https://www.cnblogs.com/qingjiuling/p/11678883.html