第一印象就是我不会做
这道题第一印象就是DP,然而并没有好的想法。
最终看好兄弟们的题解才知道如何dp我太菜了88888
先针对每一个数字求出数组二维前缀和(即每一个字母在
(
1
,
1
)
(1,1)
(1,1)到
(
i
,
j
)
(i,j)
(i,j)出现的次数)
f
[
i
]
[
j
]
[
k
]
=
m
a
x
(
f
[
i
−
1
]
[
j
−
1
]
[
k
−
1
]
,
f
[
i
]
[
j
−
1
]
[
k
−
1
]
,
f
[
i
−
1
]
[
j
]
[
k
−
1
]
,
f
[
i
]
[
j
]
[
k
−
1
]
)
f[i][j][k]=max(f[i-1][j-1][k-1],f[i][j-1][k-1],f[i-1][j][k-1],f[i][j][k-1])
f[i][j][k]=max(f[i−1][j−1][k−1],f[i][j−1][k−1],f[i−1][j][k−1],f[i][j][k−1])
唯一没有算入的情况就是整个区域都是合法区域的时候,我们只需要在判断一下即可。判断的时候就需要二维前缀和来计算个数。
然后我们只需要枚举的判断给定区域就好了
#include<iostream>
using namespace std;
int n,m,t,ans;
char a[505][505];
int f[505][505][505];
int sum[505][505][4];
int get(char x){
if(x=='R') return 0;
if(x=='G') return 1;
if(x=='Y') return 2;
if(x=='B') return 3;
return -1;
}
bool check(int x,int y,int l)
{
if (sum[x][y][3] - sum[x - l / 2][y][3] - sum[x][y - l / 2][3] + sum[x - l / 2][y - l / 2][3] != l * l / 4)
return false;
if (sum[x][y - l / 2][2] - sum[x][y - l][2] - sum[x - l / 2][y - l / 2][2] + sum[x - l / 2][y - l][2] != l * l / 4)
return false;
if (sum[x - l / 2][y][1] - sum[x - l][y][1] - sum[x - l / 2][y - l / 2][1] + sum[x - l][y - l / 2][1] != l * l / 4)
return false;
if (sum[x - l / 2][y - l / 2][0] - sum[x - l][y - l / 2][0] - sum[x - l / 2][y - l][0] + sum[x - l][y - l][0] != l * l / 4)
return false;
return true;
}
void prework(){
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++) {
for (int k = 0; k < 4; k++)
sum[i][j][k] = sum[i - 1][j][k] + sum[i][j - 1][k] - sum[i - 1][j - 1][k];
sum[i][j][get(a[i][j])]++;
}
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
for(int k=1;k<=min(i,j);k++){
f[i][j][k]=max(f[i][j][k-1],max(f[i-1][j][k-1],max(f[i][j-1][k-1],f[i-1][j-1][k-1])));
if(!(k&1)&&check(i,j,k))
f[i][j][k]=k;
}
}
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
cin>>n>>m>>t;
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
cin>>a[i][j];
prework();
int r1,r2,c1,c2;
while(t--){
ans=0;
cin>>r1>>c1>>r2>>c2;
int k=min(r2-r1+1,c2-c1+1);
if(r2-r1>c2-c1)
for(int j=r2;j-k+1>=r1;j--)
ans=max(ans,f[j][c2][k]);
else
for(int j=c2;j-k+1>=c1;j--)
ans=max(ans,f[r2][j][k]);
cout<<ans*ans<<endl;
}
return 0;
}