题解 - W R WR WR系列之—— [ W R − 5 ] [WR-5] [WR−5]圈钱行为
题目链接
S o l Sol Sol
方法一
随便暴力枚举,我具体没写过。
期望得分 10 10 10
方法二
首先我们要发现一个结论:对于一个 2 × 2 2×2 2×2的矩阵如果里面包含偶数个 A A A一定能把他变成全 A A A的,可以画个图看看。然后可以这样子想——如若大矩形能做到全 A A A,当且仅当其所有 2 × 2 2×2 2×2 子格都是偶数个 A A A。于是暴力找到一个最大的只包含偶数个 A A A的矩形就好了。
综合算法一期望得分 40 40 40
方法三
只要输出 n × m n\times m n×m即可
综合算法一、二期望得分 50 50 50
方法四
其实想到方法二的结论就好了,只要用单调栈维护一下即可,一道经典题,没什么好说的。
期望得分 100 100 100
#include <bits/stdc++.h>
using namespace std;
inline int read()
{
int sum=0,ff=1; char ch=getchar();
while(!isdigit(ch))
{
if(ch=='-') ff=-1;
ch=getchar();
}
while(isdigit(ch))
sum=sum*10+(ch^48),ch=getchar();
return sum*ff;
}
const int N=2e3+5;
int n,m,is[N][N],ls[N][N],L[N],R[N];
int stak[N],a[N][N],ans,top;
char ch[N][N];
int main()
{
n=read();
m=read();
ans=max(ans,max(n,m));
for ( int i=1;i<=n;i++ )
{
scanf("%s",ch[i]+1);
for ( int j=1;j<=m;j++ )
a[i][j]=(ch[i][j]=='A');
}
for ( int i=1;i<n;i++ )
for ( int j=1;j<m;j++ )
{
int gs=a[i][j]+a[i+1][j]+a[i][j+1]+a[i+1][j+1];
if(!(gs&1)) is[i][j]=1;
}
for ( int i=1;i<=n;i++ )
for ( int j=1;j<=m;j++ )
ls[i][j]=(is[i][j])?ls[i-1][j]+1:0;
for ( int i=1;i<=n;i++ )
{
stak[top=1]=0;
for ( int j=1;j<m;j++ )
{
while(top&&ls[i-1][stak[top]]>=ls[i-1][j]) top--;
L[j]=stak[top];
stak[++top]=j;
}
stak[top=1]=m;
for ( int j=m-1;j>=1;j-- )
{
while(top&&ls[i-1][stak[top]]>=ls[i-1][j]) top--;
R[j]=stak[top];
stak[++top]=j;
}
for ( int j=1;j<m;j++ )
ans=max(ans,(R[j]-L[j])*(ls[i-1][j]+1));
}
printf("%d\n",ans);
return 0;
}