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;
}
原文地址:https://www.cnblogs.com/limil/p/12770580.html