zoukankan      html  css  js  c++  java
  • cf1200 D White Lines(二维差分)

    题目大意

    有一个大小为n的矩阵,每个1*1的单位为黑或白,我们可以用一个(只有一个)大小为k*k的白色矩阵覆盖,问:最多的时候有几条白线(横的全为白 或竖的全为白 即为白线)。

    思路

    要想把一条线(以横的为例)全变为白的,那么我们就需要从这一行最左边的黑色块覆盖到最右边的黑色块,如果两端距离超过k,则无法覆盖,否则就一定可以。那么就一定会产生一个矩阵,选取这个矩阵里面的任何一个点 都可以将这行变为白线;反之,矩阵外的一定不行。所以,可以用差分数组,因为只要选了矩阵里的点,答案就一定就加一。然后二维前缀和,最后max取答案。

    代码

    #include <stdio.h>
    #include <queue>
    #include <string>
    #include <string.h>
    #include <algorithm>
    #include <math.h>
    using namespace std;
    typedef long long int ll;
    const int maxn = 2e3 + 10;
    const ll inf = 0x3f3f3f3f;
    int res[maxn][maxn];
    char mp[maxn][maxn];
    int main()
    {
        int n,k,ans,anss;
        while(scanf("%d%d",&n,&k) != EOF){
            for(int i = 1;i <= n;i++)
                scanf("%s",mp[i] + 1);
            memset(res,0,sizeof(res));
            ans = anss = 0;
    
            for(int i = 1;i <= n;i++){
                int mi = n + 1,mx = 0;
                for(int j = 1;j <= n;j++){
                    if(mp[i][j] == 'B'){
                        mi = min(j,mi);
                        mx = max(j,mx);
                    }
                }
                if(mx == 0){
                    anss++;
                    continue;
                }
                if(mx - mi + 1 > k)
                    continue;
                res[max(i - k + 1,1)][max(mx - k + 1,1)]++;
                res[max(i - k + 1,1)][mi + 1]--;
                res[i + 1][max(mx - k + 1,1)]--;
                res[i + 1][mi + 1]++;
            }
            for(int i = 1;i <= n;i++){
                int mi = n + 1,mx = 0;
                for(int j = 1;j <= n;j++){
                    if(mp[j][i] == 'B'){
                        mi = min(j,mi);
                        mx = max(j,mx);
                    }
                }
                if(mx == 0){
                    anss++;
                    continue;
                }
                if(mx - mi + 1 > k)
                    continue;
                res[max(mx - k + 1,1)][max(i - k + 1,1)]++;
                res[mi + 1][max(i - k + 1,1)]--;
                res[max(mx - k + 1,1)][i + 1]--;
                res[mi + 1][i + 1]++;
            }
    
            for(int i = 1;i <= n;i++){
                for(int j = 1;j <= n;j++){
                    res[i][j] += res[i - 1][j] + res[i][j - 1] - res[i - 1][j - 1];
                    ans = max(ans,res[i][j]);
                }
            }
    
            printf("%d
    ",ans + anss);
        }
        return 0;
    }
  • 相关阅读:
    在Linux中安装Oracle(较详细图解)
    SecureCRT
    MHA配置文件说明
    MySQL建表规范与常见问题 (go)
    Shell编程时常用的系统文件(转)
    Leetcode: Excel Sheet Column Title
    Leetcode: Find Peak Element
    Leetcode: Intersection of Two Linked Lists
    Leetcode: Majority Element
    Summary: Class Variable vs. Instance Variable && Class Method
  • 原文地址:https://www.cnblogs.com/InitRain/p/12293595.html
Copyright © 2011-2022 走看看