题解:如果满足给定条件的正方形,只要正方形的每一行中都为相同的就行了,不用管是否是good土地,因为可以使用MDT对于每一行进行转换。预处理,对于每一行的每一个位置,如果这一行当前位置和前一个位置是不同的那么这个位置就为1,对于每一个正方形,我们把行减小一列进行二维前缀和,如果二维前缀和的值为0,那么这个正方形就满足条件,但是因为枚举每个正方形会超时,那么我们可以对于每一个为正方形的右下点,二分枚举正方形的长度。
代码:
#include <bits/stdc++.h>
using namespace std;
char mp[1005][1005];
int num[1005][1005];
int check(int i,int j,int mid){
int fx=i-mid,fy=j-mid+1;
if(num[i][j]-num[i][fy]-num[fx][j]+num[fx][fy]==0) return 1;
return 0;
}
int main()
{
int n,m;
scanf("%d %d",&n,&m);
for(int i=1;i<=n;i++){
scanf("%s",mp[i]+1);
}
for(int i=1;i<=n;i++){
for(int j=2;j<=m;j++){
if(mp[i][j]!=mp[i][j-1]) num[i][j]=1;
}
}
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++){
num[i][j]+=num[i-1][j]+num[i][j-1]-num[i-1][j-1];
}
}
int ans=0;
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++){
int l=1,r=min(i,j),flag=0;
while(l<=r){
int mid=(l+r)>>1;
if(check(i,j,mid)) l=mid+1,flag=mid;
else r=mid-1;
}
ans=max(ans,flag*flag);
}
}
cout<<ans<<endl;
return 0;
}