https://codeforces.com/contest/1200/problem/D
題意:給出一個n*n的由BW組成的點陣,有一個橡皮擦可以使左上角爲x,y,邊長爲k的矩陣中B變成W,通過一次操作使得行和列全爲w的數量最多,求出這個數量
思路:時間複雜度肯定爲O(n2),所以考慮如何枚舉每個點的同時就能直接求出每個點的貢獻。
首先滿足一行在這個方塊內時,需要最左邊方塊和最右邊方塊都在內部。
一列在方塊內時,需要最上面和最下面方塊在內部
當我們每次向右邊移動一列時,我們這個方塊,最左邊會出去一列,右邊會進來一列,那麼列的貢獻只需要O(1)判斷,如果左邊原來有cnt–,右邊進來cnt++,一開始通過k2計算出來初始矩陣的貢獻,但是行的貢獻需要O(K) 顯然不能同時計算行列的貢獻,所以直接分開計算行列貢獻,最後判斷行列貢獻值最大即可
注意如果一開始未操作時就全爲W,不進入cnt計算
#include<bits/stdc++.h>
#include<tr1/unordered_map>
#define fi first
#define se second
#define show(a) cout<<a<<endl;
#define show2(a,b) cout<<a<<" "<<b<<endl;
#define show3(a,b,c) cout<<a<<" "<<b<<" "<<c<<endl;
#define max3(a,b,c) max(a,max(b,c))
#define min3(a,b,c) min(a,min(b,c))
using namespace std;
typedef long long ll;
typedef pair<int, int> P;
typedef pair<P, int> LP;
const int inf = 0x3f3f3f3f;
const int N = 2e3 + 100;
const int mod = 10007;
const int base=131;
tr1::unordered_map<ll,ll> mp;
char s[2005][2005];
int n,k;
bool row[2005],col[2005];
int l[N],r[N],up[N],dw[N];
int cnt,x,y;
int a[N][N],b[N][N];
int main()
{
scanf("%d%d",&n,&k);
for(int i=1;i<=n;i++) scanf("%s",s[i]+1);
for(int i=1;i<=n;i++)
{
int flag=0;
for(int j=1;j<=n;j++)
if(s[i][j]=='B')
{
flag=1;
if(!l[i]) l[i]=j;
r[i]=j;
}
if(flag==0) row[i]=1,x++;
flag=0;
for(int j=1;j<=n;j++)
if(s[j][i]=='B')
{
flag=1;
if(!up[i]) up[i]=j;
dw[i]=j;
}
if(flag==0) col[i]=1,y++;
//if(row[i]||col[i]) cout<<i<<endl;
}
for(int j=1;j+k-1<=n;j++)
for(int i=1;i+k-1<=n;i++)
{
if(i==1)
{
cnt=x;
for(int c=1;c<=k;c++)
{
if(row[c]) continue;
if(l[c]>=j&&r[c]<=j+k-1) cnt++;
}
a[i][j]=cnt;
}
else
{
if(!row[i-1])
{
if(l[i-1]>=j&&r[i-1]<=j+k-1) cnt--;
}
if(!row[i+k-1])
{
if(l[i+k-1]>=j&&r[i+k-1]<=j+k-1) cnt++;
}
a[i][j]=cnt;
}
}
for(int i=1;i+k-1<=n;i++)
for(int j=1;j+k-1<=n;j++)
{
if(j==1)
{
cnt=y;
for(int c=1;c<=k;c++)
{
if(col[c]) continue;
if(up[c]>=i&&dw[c]<=i+k-1) cnt++;
}
b[i][j]=cnt;
}
else
{
if(!col[j-1])
{
if(up[j-1]>=i&&dw[j-1]<=i+k-1) cnt--;
}
if(!col[j+k-1])
{
if(up[j+k-1]>=i&&dw[j+k-1]<=i+k-1) cnt++;
}
b[i][j]=cnt;
}
}
int ans=0;
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
ans=max(ans,a[i][j]+b[i][j]);
printf("%d",ans);
}