Palindrome Sub-Array
Time Limit: 3000/1000 MS (Java/Others) Memory Limit: 65535/32768 K (Java/Others)Total Submission(s): 162 Accepted Submission(s): 72
Problem 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.
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
Source
Recommend
zhuyuanchen520
下午上班的时候无语大神随便找了多校一题说我们学校的都没过,过去一看,想了下思路,其实这个思路一直感觉会超时,因为复杂度超高,但是无语说他直觉能过,于是回来写了果然过了,速度还蛮快。
求一个矩阵横着竖着都是回文。
枚举中点,然后每次往外扩一圈,判断这一圈中以中点成中心对称的四个点是不是相等,如果相等就一直往外扩。
加一点点剪枝。另外,分两种讨论,一种是中点是一个点的,另外一种是中点为四个点组成的2*2矩形。
代码
#include <stdio.h>
#include <string.h>
#include <algorithm>
using namespace std;
int a[305][305];
int ans;
int n,m;
int CountEven(int x,int y)
{
int i,j;
int tmp=min(x,y);
tmp=min(tmp,min(n-x-2,m-y-2));
//? if (2*tmp+2<ans) return 0;
for (i=0;i<=tmp;i++)
{
for (j=0;j<=i;j++)
{
if (!(a[x-j][y+i+1]==a[x+j+1][y+i+1] && a[x+j+1][y+i+1]==a[x+j+1][y-i] && a[x-j][y-i]==a[x+j+1][y+i+1])) return 2*i;
if (!(a[x-i][y+j+1]==a[x+i+1][y+j+1] && a[x+i+1][y+j+1]==a[x+i+1][y-j] && a[x-i][y-j]==a[x+i+1][y+j+1])) return 2*i;
// printf("%d %d %d,%d %d %d,%d %d %d,%d %d %d\n",x-j,y+i+1,a[x-j][y+i+1],x+j+1,y+i+1,a[x+j+1][y+i+1],x+j+1,y-i,a[y+j+1][y-i],x-j,y-i,a[x-j][y-i]);
// printf("%d %d,%d %d,%d %d,%d %d\n",x-i,y+j+1,x+i+1,y+j+1,x+i+1,y-j,x-i,y-j);
}
// printf("%d %d %d!\n",x,y,i);
}
return 2*i;
}
int CountOdd(int x,int y)
{
int i,j;
int tmp=min(x,y);
tmp=min(tmp,min(n-x-1,m-y-1));
if (2*tmp+1<ans) return 0;
for (i=1;i<=tmp;i++)
{
for (j=0;j<=i;j++)
{
if (!(a[x-j][y-i]==a[x+j][y+i] && a[x-j][y+i]==a[x-j][y-i] && a[x+j][y-i]==a[x-j][y+i])) return 2*(i-1)+1;
if (!(a[x-i][y-j]==a[x+i][y+j] && a[x-i][y+j]==a[x-i][y-j] && a[x+i][y-j]==a[x-i][y+j])) return 2*(i-1)+1;
// printf("%d %d %d,%d %d %d,%d %d %d,%d %d %d\n",x-j,y-i,a[x-j][y-i],x+j,y+i,a[x+j][y+i],x-j,y+i,a[x-j][y+i],x+j,y-i,a[x+j][y-i]);
// printf("%d %d,%d %d,%d %d,%d %d\n",x-i,y-j,x+i,y+j,x-i,y+j,x+i,y-j);
}
// printf("%d %d %d~\n",x,y,i);
}
return 2*(i-1)+1;
}
int main()
{
int i,j,T;
scanf("%d",&T);
while(T--)
{
scanf("%d%d",&n,&m);
for (i=0;i<n;i++)
{
for (j=0;j<m;j++)
{
scanf("%d",&a[i][j]);
}
}
ans=0;
for (i=0;i<n;i++)
{
for (j=0;j<m;j++)
{
ans=max(ans,CountOdd(i,j));
}
}
for (i=0;i<n-1;i++)
{
for (j=0;j<m-1;j++)
{
ans=max(ans,CountEven(i,j));
}
}
printf("%d\n",ans);
}
return 0;
}