hdu4618 Palindrome Sub-Array

来源:互联网 发布:程控电话交换机编程 编辑:程序博客网 时间:2024/06/06 01:47

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.
 

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

Sample Input
15 101 2 3 3 2 4 5 6 7 81 2 3 3 2 4 5 6 7 81 2 3 3 2 4 5 6 7 81 2 3 3 2 4 5 6 7 81 2 3 9 10 4 5 6 7 8
 

Sample Output
4
 

Source
2013 Multi-University Training Contest 2
 

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;}