HDU 2870

题目: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;
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值