Cut the cake
Time Limit: 6000/3000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)Total Submission(s): 68 Accepted Submission(s): 26
Problem Description
Mark bought a huge cake, because his friend ray_sun’s birthday is coming. Mark is worried about how to divide the cake since it’s so huge and ray_sun is so strange. Ray_sun is a nut, you can never imagine how strange he was, is, and going to be. He does not eat rice, moves like a cat, sleeps during work and plays games when the rest of the world are sleeping……It is not a surprise when he has some special requirements for the cake. A considering guy as Mark is, he will never let ray_sun down. However, he does have trouble fulfilling ray_sun’s wish this time; could you please give him a hand by solving the following problem for him?
The cake can be divided into n*m blocks. Each block is colored either in blue or red. Ray_sun will only eat a piece (consisting of several blocks) with special shape and color. First, the shape of the piece should be a rectangle. Second, the color of blocks in the piece should be the same or red-and-blue crisscross. The so called ‘red-and-blue crisscross’ is demonstrated in the following picture. Could you please help Mark to find out the piece with maximum perimeter that satisfies ray_sun’s requirements?
The cake can be divided into n*m blocks. Each block is colored either in blue or red. Ray_sun will only eat a piece (consisting of several blocks) with special shape and color. First, the shape of the piece should be a rectangle. Second, the color of blocks in the piece should be the same or red-and-blue crisscross. The so called ‘red-and-blue crisscross’ is demonstrated in the following picture. Could you please help Mark to find out the piece with maximum perimeter that satisfies ray_sun’s requirements?
Input
The first line contains a single integer T (T <= 20), the number of test cases.
For each case, there are two given integers, n, m, (1 <= n, m <= 1000) denoting the dimension of the cake. Following the two integers, there is a n*m matrix where character B stands for blue, R red.
For each case, there are two given integers, n, m, (1 <= n, m <= 1000) denoting the dimension of the cake. Following the two integers, there is a n*m matrix where character B stands for blue, R red.
Output
For each test case, output the cased number in a format stated below, followed by the maximum perimeter you can find.
Sample Input
2 1 1 B 3 3 BBR RBB BBB
Sample Output
Case #1: 4 Case #2: 8
Source
Recommend
zhoujiaqi2010
题意:给定一块两色的矩形,求相同颜色子矩形的最大周长,或者颜色间隔相同的最大正方形的周长
分析:这题如果做过OI的应该都很熟悉,比赛的时候没做= =,典型的最大子矩形,正方形的那个DP随便写就行,相同颜色的dp,为每个格子保存三个值,一个最高能到达的高度,在这个高度下最左的格子,和最右的格子,不会的看 王知昆的最大子矩形 那篇论文
代码:
#include<cstdio>
#include<iostream>
#include<cstring>
using namespace std;
const int mm=1111;
int f[mm][mm],g[mm][mm],h[mm],l[mm],r[mm];
char s[mm];
int i,j,k,n,m,ans,t,cs=0;
void dp(int c)
{
int i,j,lm,rm;
for(i=1;i<=m;++i)h[i]=0,l[i]=1,r[i]=m;
for(i=1;i<=n;++i)
{
lm=1,rm=m;
for(j=1;j<=m;++j)
if(c-g[i][j])
{
++h[j];
if(l[j]<lm)l[j]=lm;
}
else h[j]=0,lm=j+1,l[j]=1,r[j]=m;
for(j=m;j>0;--j)
if(h[j])
{
if(r[j]>rm)r[j]=rm;
ans=max(ans,(h[j]+r[j]-l[j]+1)*2);
}
else rm=j-1;
}
}
int main()
{
scanf("%d",&t);
while(t--)
{
scanf("%d%d",&n,&m);
for(i=1;i<=n;++i)
{
scanf("%s",s);
for(j=0;j<m;++j)
g[i][j+1]=(s[j]=='B');
}
for(i=1;i<=n;++i)
for(j=1;j<=m;++j)
{
f[i][j]=1;
if(g[i][j-1]!=g[i][j]&&g[i-1][j]!=g[i][j])
{
k=min(f[i][j-1],f[i-1][j]);
if(f[i][j-1]==f[i-1][j]&&g[i-k][j-k]!=g[i][j]);
else ++k;
f[i][j]=max(f[i][j],k);
}
}
ans=0;
for(i=1;i<=n;++i)
for(j=1;j<=m;++j)
ans=max(ans,f[i][j]*4);
dp(0);
dp(1);
printf("Case #%d: %d\n",++cs,ans);
}
}