zoukankan      html  css  js  c++  java
  • Codeforces 1200D

    Description

    思路

    以行为例,求每一行中存在黑颜色的左边界l和右边界r。那么橡皮擦必须要完全覆盖到这个区间[l, r]才可以使得这一行为白色。那么反过来,如果我们知道这个区间,我们就可以求所有完全覆盖这个区间的橡皮擦所在的位置(是一个矩形范围的区域)。这个区间对这个矩形区域的贡献为1,可以用二维差分。
    列也一样这样处理。

    #include <bits/stdc++.h>
     
    using namespace std;
    const int N = 3e3;
    typedef long long ll;
     
    char mp[N][N];
    int lie[N][2];
    int han[N][2];
    int ans[N][N];
     
    int main() {
        ios::sync_with_stdio(false);
        int n, k;
        cin >> n >> k;
        for(int i = 1; i <= n; i++) {
            cin >> mp[i] + 1;
        }
        for(int i = 1; i <= n; i++) {
            for(int j = 1; j <= n; j++) {
                if(mp[i][j] == 'B') {
                    han[i][0] = j;
                    break;
                }
            }
            for(int j = n; j >= 1; j--) {
                if(mp[i][j] == 'B') {
                    han[i][1] = j;
                    break;
                }
            }
        }
        for(int i = 1; i <= n; i++) {
            for(int j = 1; j <= n; j++) {
                if(mp[j][i] == 'B') {
                    lie[i][0] = j;
                    break;
                }
            }
            for(int j = n; j >= 1; j--) {
                if(mp[j][i] == 'B') {
                    lie[i][1] = j;
                    break;
                }
            }
        }
        for(int i = 1; i <= n; i++) {
            int l = han[i][0], r = han[i][1];
            if(l == r && l == 0) {
                ans[1][1] += 1;
            }
            if(r - l + 1 > k) continue;
            int x1 = max(1, r - k + 1), y1 = max(1, i - k + 1);
            int x2 = l, y2 = i;
            ans[y1][x1] += 1;
            ans[y2 + 1][x1] -= 1;
            ans[y1][x2 + 1] -= 1;
            ans[y2 + 1][x2 + 1] += 1;
        }
        for(int i = 1; i <= n; i++) {
            int l = lie[i][0], r = lie[i][1];
            if(l == r && l == 0) {
                ans[1][1] += 1;
            }
            if(r - l + 1 > k) continue;
            int y1 = max(1, r - k + 1), x1 = max(1, i - k + 1);
            int x2 = i, y2 = l;
            ans[y1][x1] += 1;
            ans[y2 + 1][x1] -= 1;
            ans[y1][x2 + 1] -= 1;
            ans[y2 + 1][x2 + 1] += 1;
        }
        int tans = 0;
        for(int i = 1; i <= n - k + 1; i++) {
            for(int j = 1; j <= n - k + 1; j++) {
                ans[i][j] += ans[i - 1][j] + ans[i][j - 1] - ans[i - 1][j - 1];
                tans = max(ans[i][j], tans);
            }
        }
        cout << tans << endl;
    }
    
  • 相关阅读:
    C#与独孤九剑
    C#系列视频教程字符和字符串操作
    【设计模式】迪米特法则
    【设计模式】考题 模板方法模式
    C#字符和字符串
    【热门技术】解决Win7 下面很多软件安装不兼容的问题
    C#使电脑发出嗡鸣声
    C#视频教程下载(第一章)
    【设计模式】牛市股票还会亏钱 外观模式
    【设计模式】好菜每回味不同 建造者模式
  • 原文地址:https://www.cnblogs.com/limil/p/12770580.html
Copyright © 2011-2022 走看看