Cut the cake
Time Limit: 6000/3000 MS (Java/Others)
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?
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.
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
题意:找一个最大矩阵,要么矩阵内所有元素都一样,要么相邻不一样.
思路:只需做两个标记,一个是与上面方块一样的时候的最高最左最右,一个是不一样的时候的最高最左最右.
代码:
#include<bits/stdc++.h>
#define mem(a,b) memset(a,b,sizeof(a))
using namespace std;
typedef long long ll;
const ll mod = 1000000007;
const int maxn = 1e5+5;
int n,m;
char mp[1234][1234];
int l[1234][1234][3],r[1234][1234][3],u[1234][1234][3],ml[1234][1234][3],mr[1234][1234][3];
int main()
{
int t,cnt = 0;
cin>>t;
while(t--)
{
mem(mp,0);
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 = 1;j<= m;j++)
{
l[i][j][1] = mp[i][j] == mp[i][j-1]?l[i][j-1][1]:j;
l[i][j][2] = (mp[i][j] == mp[i][j-1]||j == 1)?j:l[i][j-1][2];
}
}
for(int i = 1;i<= n;i++)
{
for(int j = m;j>= 1;j--)
{
r[i][j][1] = mp[i][j] == mp[i][j+1]?r[i][j+1][1]:j;
r[i][j][2] = (mp[i][j] == mp[i][j+1]||j == m)?j:r[i][j+1][2];
}
}
int ans = 0;
for(int i = 1;i<= n;i++)
{
for(int j = 1;j<= m;j++)
{
if(i> 1&&mp[i][j]!= mp[i-1][j])
{
ml[i][j][1] = l[i][j][1];
mr[i][j][1] = r[i][j][1];
u[i][j][1] = 1;
ml[i][j][2] = max(l[i][j][2],ml[i-1][j][2]);
mr[i][j][2] = min(r[i][j][2],mr[i-1][j][2]);
u[i][j][2] = u[i-1][j][2]+1;
}
else if(i> 1&&mp[i][j] == mp[i-1][j])
{
ml[i][j][2] = l[i][j][2];
mr[i][j][2] = r[i][j][2];
u[i][j][2] = 1;
ml[i][j][1] = max(l[i][j][1],ml[i-1][j][1]);
mr[i][j][1] = min(r[i][j][1],mr[i-1][j][1]);
u[i][j][1] = u[i-1][j][1]+1;
}
else
{
ml[i][j][1] = l[i][j][1];
mr[i][j][1] = r[i][j][1];
u[i][j][1] = 1;
ml[i][j][2] = l[i][j][2];
mr[i][j][2] = r[i][j][2];
u[i][j][2] = 1;
}
ans = max(ans,max(((mr[i][j][1]-ml[i][j][1]+1)+u[i][j][1])*2,((mr[i][j][2]-ml[i][j][2]+1)+u[i][j][2])*2));
}
}
printf("Case #%d: %d\n",++cnt,ans);
}
return 0;
}