题意:给你n k,矩形面积n * n,橡皮尺寸k * k。橡皮只能使用一次,问你使用过后white line(白色横行+白色竖行)最多有多少条?
思路:
各种前缀和qaq
tu——原本的图;G——01图black映射成1,white映射成0;
GR,GC——对图G分别就行 列求前缀和
chan_R,chan_C,以当前i,j坐标为eraser左边界(上边界)是否会对这一列(行)有贡献(增添一个white line)
add_R,对chan_C求前缀和表示add_R[i][j]对于row-i,从第1列到第j列有多少能变成column of white
add_C,对chan_R求前缀和表示add_C[i][j]对于column-j,从第1行到第i列有多少能变成row of white
求MaxAns是卡住一个k * k求max + 原本就存在的white lines
AC代码
#include<cstdio>
#include<iostream>
#include<cstring>
#include<string>
using namespace std;
int n,k,ans,ANS;
char tu[2005][2005];
int G[2005][2005];
int GR[2005][2005],GC[2005][2005];
bool chan_R[2005][2005],chan_C[2005][2005];
int add_R[2005][2005],add_C[2005][2005];
int main()
{
scanf("%d %d",&n,&k);
ans = 0;
for(int i = 1;i <= n; i++){
for(int j = 1;j <= n; j++){
scanf(" %c",&tu[i][j]);
if(tu[i][j] == 'B') G[i][j] = 1;
}
}
//R 行 C 列
for(int i = 1;i <= n; i++){
for(int j = 1;j <= n; j++){
GR[i][j] = GR[i][j - 1] + G[i][j];
GC[i][j] = GC[i - 1][j] + G[i][j];
}
}
for(int i = 1;i <= n; i++){
if(!GR[i][n]) ans++;
if(!GC[n][i]) ans++;
}
//已经拥有的 white lines
for(int i = 1;i <= n; i++){
for(int j = 1;j + k - 1 <= n; j++){
if(GR[i][n]){
chan_R[i][j] = (GR[i][j + k - 1] - GR[i][j - 1] == GR[i][n]);
}
if(GC[n][i]){
chan_C[j][i] = (GC[j + k - 1][i] - GC[j - 1][i] == GC[n][i]);
}
}
}
//eraser 在(i,j)作为左上角时 if(this row turn to white)
//eraser 在(j,i)作为左上角时 if(this column turn to white)
/*
cout << "-------------------------"<<endl;
for(int i = 1;i <= n ;i++){
for(int j = 1;j <= n; j++){
cout << chan_R[i][j] << " ";
}
cout << endl;
}
cout << "--------------------------"<<endl;
for(int i = 1;i <= n ;i++){
for(int j = 1;j <= n; j++){
cout << chan_C[i][j] << " ";
}
cout << endl;
}
*/
for(int i = 1;i <= n; i++){
for(int j = 1;j <= n; j++){
add_R[i][j] = add_R[i][j - 1] + chan_C[i][j];
add_C[i][j] = add_C[i - 1][j] + chan_R[i][j];
}
}
/*
cout << "-------------------------"<<endl;
for(int i = 1;i <= n ;i++){
for(int j = 1;j <= n; j++){
cout << add_R[i][j] << " ";
}
cout << endl;
}
cout << "--------------------------"<<endl;
for(int i = 1;i <= n ;i++){
for(int j = 1;j <= n; j++){
cout << add_C[i][j] << " ";
}
cout << endl;
}
cout <<"-----------------------------------------------\n";
*/
ANS = 0;
for(int i = 1;i + k - 1 <= n; i++){
for(int j = 1;j + k - 1 <= n; j++){
int cur = add_R[i][j + k - 1] - add_R[i][j - 1] + add_C[i + k - 1][j] - add_C[i - 1][j];
ANS = max(ANS,cur);
}
}
printf("%d\n",ANS + ans);
}