题意:给定一块两色的矩形,求相同颜色子矩形的最大周长,或者颜色间隔相同的最大正方形的周长!!
代码:
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<memory.h>
using namespace std;
const int maxn=1002;
int n,m,t,ans,cas=1;
int f[maxn][maxn];///图形转换
int dp[maxn][maxn];
int h[maxn][maxn];///h[i,j]为点(i,j)对应的悬线的长度。
int l[maxn][maxn];///l[i,j]为点(i,j)对应的悬线向左最多能够移动到的位置。
int r[maxn][maxn];///r[i,j]为点(i,j)对应的悬线向右最多能够移动到的位置。
char g[maxn][maxn];///图像
int DP(int n,int m,int cmd)
{
int i,j,k,res=0,lm,rm;
for(i=0; i<=n; i++)
for(j=0; j<=m; j++)
{
h[i][j]=0,l[i][j]=1,r[i][j]=m;
}
//cout<<"i j h l r ans:"<<endl;
for(i=1; i<=n; i++)
{
for(j=1; j<=m; j++)
{
if(cmd==f[i][j])///不是障碍点
{
h[i][j]=h[i-1][j]+1;
lm=l[i-1][j];
for(k=j-1; k>=1&&k>=lm; k--)
{
if(f[i][k]!=cmd)
{
lm=max(lm,k+1);
break;
}
}
l[i][j]=lm;
rm=r[i-1][j];
for(k=j+1; k<=m&&k<=rm; k++)
{
if(f[i][k]!=cmd)
{
rm=min(rm,k-1);
break;
}
}
r[i][j]=rm;
// int Max=min();
res=max(res,(h[i][j]+r[i][j]-l[i][j]+1)*2);
//cout<<i<<" "<<j<<" "<<h[i][j]<<" "<<l[i][j]<<" "<<r[i][j]<<" "<<((h[i][j]+r[i][j]-l[i][j]+1)*2)<<endl;
}
}
}
return res;
}
int DP()
{
int i,j,k,res=0;
for(i=1; i<=n; ++i)
{
for(j=1; j<=m; ++j)
{
dp[i][j]=1;
if(f[i][j-1]!=f[i][j]&&f[i-1][j]!=f[i][j])
{
k=min(dp[i][j-1],dp[i-1][j]);
if(dp[i][j-1]==dp[i-1][j]&&f[i-k][j-k]!=f[i][j]);
else ++k;
dp[i][j]=max(dp[i][j],k);
}
res=max(res,dp[i][j]*4);
}
}
return res;
}
int main()
{
//freopen("C:\\Documents and Settings\\Administrator\\桌面\\第3次多校联合比赛标程+数据+题解\\1009\\1009.in" , "r" , stdin);
//freopen("C:\\Documents and Settings\\Administrator\\桌面\\第3次多校联合比赛标程+数据+题解\\1009\\myoutput.txt" , "w" , stdout);
scanf("%d",&t);
while(t--)
{
memset(dp,0,sizeof(dp));
scanf("%d%d",&n,&m);
ans=0;
for(int i=1; i<=n; i++)
{
scanf("%s",&g[i]);
for(int j=1; j<=m; j++)
{
f[i][j]=(g[i][j-1]=='R'?1:0);
}
}
ans=DP(n,m,1);
ans=max(DP(n,m,0),ans);
ans=max(ans,DP());
printf("Case #%d: %d\n",cas++,ans);
}
return 0;
}