题目:http://acm.hdu.edu.cn/showproblem.php?pid=2870
这题若先把w,x,y,z都转换成对应的字符(a,b,c)中的一种,则可转换成求由相同字符构成的最大矩阵,后面的做法就和和HDU 1505这题类似了。
h[i][j]表示以在某一行以第i列为底以第j种字符的最大高度。以此高度向左右分别扩散,找到高度大于等于当前高度的左边界lef[i]和右边界rig[i],则以此高度构成的相同字符的最大矩阵的大小为:h[i][j]*(rig[i]-lef[i]);遍历每一行即可找到所求答案。
#include <cstdio>
#include <cstring>
#include <string>
#include <queue>
#include <stack>
#include <vector>
#include <map>
#include <iostream>
#include <algorithm>
using namespace std;
#define ll long long
#define int64 __int64
#define M 1005
int n , m , h[M][3] , lef[M] , rig[M];
char matrix[M][M];
void Cal(int k , char ch)//对当前列的高度更新
{
if (ch == 'a')
{
h[k][0]++;
h[k][1] = 0;
h[k][2] = 0;
}
else if (ch == 'b')
{
h[k][0] = 0;
h[k][1]++;
h[k][2] = 0;
}
else if (ch == 'c')
{
h[k][0] = 0;
h[k][1] = 0;
h[k][2]++;
}
else if (ch == 'w')
{
h[k][0]++;
h[k][1]++;
h[k][2] = 0;
}
else if (ch == 'x')
{
h[k][0] = 0;
h[k][1]++;
h[k][2]++;
}
else if (ch == 'y')
{
h[k][0]++;
h[k][1] = 0;
h[k][2]++;
}
else
{
h[k][0]++;
h[k][1]++;
h[k][2]++;
}
}
int Solve()
{
int i , j , l , ret = 0;
memset(h , 0 , sizeof h);
h[0][0] = h[0][1] = h[0][2] = -1;
h[m+1][0] = h[m+1][1] = h[m+1][2] = -1;
for (i = 1 ; i <= n ; i++)
{
for (j = 1 ; j <= m ; j++)
{
Cal(j,matrix[i][j]);
}
for (l =0 ; l < 3 ; l++)
{
for (j = 1 ; j <= m ; j++)
{
lef[j] = j;
while (h[lef[j]-1][l] >= h[j][l])
lef[j] = lef[lef[j]-1];
}
for (j = m ; j >= 1 ; j--)
{
rig[j] = j;
while (h[rig[j]+1][l] >= h[j][l])
rig[j] = rig[rig[j]+1];
}
int MAX;
for (j = 1 ; j <= m ; j++)
{
MAX = h[j][l]*(rig[j]-lef[j]+1);
ret = max(ret,MAX);
}
}
}
return ret;
}
int main()
{
while (~scanf("%d%d",&n,&m))
{
int i;
for (i = 1 ; i <= n ; i++)scanf("%s",matrix[i]+1);
printf("%d\n",Solve());
}
return 0;
}