题目大意
有一个大小为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\n",ans + anss); } return 0; }
原文地址:https://www.cnblogs.com/InitRain/p/12293595.html
时间: 2024-10-14 06:24:41