HDU 4618 Palindrome Sub-Array 暴力

Palindrome Sub-Array

题目连接:

http://acm.hdu.edu.cn/showproblem.php?pid=4618

Description

 A palindrome sequence is a sequence which is as same as its reversed order. For example, 1 2 3 2 1 is a palindrome sequence, but 1 2 3 2 2 is not. Given a 2-D array of N rows and M columns, your task is to find a maximum sub-array of P rows and P columns, of which each row and each column is a palindrome sequence.

  

Input

  The first line of input contains only one integer, T, the number of test cases. Following T blocks, each block describe one test case.
  There is two integers N, M (1<=N, M<=300) separated by one white space in the first line of each block, representing the size of the 2-D array.
  Then N lines follow, each line contains M integers separated by white spaces, representing the elements of the 2-D array. All the elements in the 2-D array will be larger than 0 and no more than 31415926.
  

Output

  For each test case, output P only, the size of the maximum sub-array that you need to find.
  

Sample Input

1
5 10
1 2 3 3 2 4 5 6 7 8
1 2 3 3 2 4 5 6 7 8
1 2 3 3 2 4 5 6 7 8
1 2 3 3 2 4 5 6 7 8
1 2 3 9 10 4 5 6 7 8

Sample Output

4

Hint

题意

给你一个n,m的矩形,你需要找到一个最大正方形,使得每一行每一列都是回文的

输出正方形的边长

题解:

首先把奇数位置都填上-1,然后这样所有回文的东西都是奇数长度了

暴力预处理出以每一个数为中心,能够向上,向左边扩展多少

然后我们在n^2暴力枚举回文正方形的中心点,再O(N)的去check最大能扩展多少就好了

代码

#include<bits/stdc++.h>
using namespace std;

const int maxn = 701;
int M[maxn][maxn];
int M2[maxn][maxn];
int Len1[maxn][maxn],Len2[maxn][maxn];
int n,m;
void init()
{
    memset(M,0,sizeof(M));
	memset(M2,0,sizeof(M2));
	memset(Len1,0,sizeof(Len1));
	memset(Len2,0,sizeof(Len2));
}
void solve()
{
	init();
	scanf("%d%d",&n,&m);
	for(int i=1;i<=n;i++)
		for(int j=1;j<=m;j++)
			scanf("%d",&M2[i][j]);

	for(int i=1;i<=2*n+1;i++)
	{
		for(int j=1;j<=2*m+1;j++)
		{
			if(i%2==1||j%2==1)M[i][j]=-1;
			else M[i][j]=M2[i/2][j/2];
		}
	}

	n=n*2+1;
	m=m*2+1;

	for(int i=1;i<=n;i++)
	{
		for(int j=1;j<=m;j++)
		{
			int l = 0;
			for(int k=0;j-k>=1&&j+k<=m;k++)
			{
				if(M[i][j-k]==M[i][j+k])
					l=k;
				else
					break;
			}
			Len1[i][j]=l;
		}
	}

	for(int i=1;i<=n;i++)
	{
		for(int j=1;j<=m;j++)
		{
			int l = 0;
			for(int k=0;i+k<=n&&i-k>=1;k++)
			{
				if(M[i+k][j]==M[i-k][j])
					l=k;
				else
					break;
			}
			Len2[i][j]=l;
		}
	}

	int ans = 0;

	for(int i=1;i<=n;i++)
	{
		for(int j=1;j<=m;j++)
		{
			int Min1 = 1<<30;
			int Min2 = 1<<30;
			for(int l=0;i-l>=1&&i+l<=n&&j+l<=m&&j-l>=1;l++)
			{
				Min1=min(Min1,Len2[i][j-l]),Min1=min(Min1,Len2[i][j+l]);
				Min2=min(Min2,Len1[i+l][j]),Min2=min(Min2,Len1[i-l][j]);
				if(Min1<l||Min2<l)break;
				if(M[i][j]==-1)ans = max(ans,l);
				else ans = max(ans,l);
			}
		}
	}

	cout<<ans<<endl;
	return;
}
int main()
{
	int t;
	scanf("%d",&t);
	while(t--)solve();
	return 0;
}
posted @ 2016-04-10 11:06  qscqesze  阅读(255)  评论(0编辑  收藏  举报