【佛山市选2013】JZOJ2020年8月7日提高组T1 回文子序列

【佛山市选2013】JZOJ2020年8月7日提高组T1 回文子序列

题目

描述
回文序列是指左右对称的序列。例如1 2 3 2 1是回文序列,但是1 2 3 2 2就不是。我们会给定一个N×M的矩阵,你需要从这个矩阵中找出一个P×P的子矩阵,使得这个子矩阵的每一列和每一行都是回文序列。
数据
对于20%数据 1 ≤ N, M ≤ 10
对于所有数据 1 ≤ N, M ≤ 300

题解

题意
在一个 n ∗ m n*m nm的矩阵内找到一个最大的 p ∗ p p*p pp的子矩阵使得该子矩阵内的每行每列都是回文
输出 p p p
分析
这种题嘛
想打 m a n a c h e r manacher manacher也没问题,反正我是不会 (有巨佬 m a n a c h e r + d p manacher+dp manacher+dp
所以我就打暴力
枚举起点和 p p p
然后暴力判断是否合法
算一下之间复杂度
枚举起点和 p p p O ( n ∗ m ∗ m i n ( n , m ) ) O(n*m*min(n,m)) O(nmmin(n,m))
暴力判断是 O ( n 2 ∗ m 2 4 ) O(\dfrac{n^2*m^2}{4}) O(4n2m2)
所以说总的时间复杂度就是 O ( n 3 ∗ m 3 ∗ m i n ( n , m ) 4 ) O(\dfrac{n^3*m^3*min(n,m)}{4}) O(4n3m3min(n,m))
按理说 n , m ≤ 300 n,m≤300 n,m300过不去的
但数据太水就过去了QAQ

Code

#include
#include
using namespace std;
int n,m,i,j,k,u,x,y,ans,a[305][305];
bool bj;
int main()
{
    freopen("T1.in","r",stdin);
    freopen("T1.out","w",stdout);
    scanf("%d%d",&n,&m);
    for (i=1;i<=n;i++)
        for (j=1;j<=m;j++)
            scanf("%d",&a[i][j]);
    for (i=1;i<=n;i++)
        for (j=1;j<=m;j++)
            for (k=0;k<=n-i&&k<=m-j;k++)
            {
                bj=true;
                for (u=i;u<=i+k;u++)
                {
                    x=j;
                    y=j+k;
                    while (x<=y)
                    {
                        if (a[u][x]!=a[u][y]) 
                        {
                            bj=false;
                            break;
                        }
                        x++;
                        y--;
                    }
                    if (bj==false) break;
                }
                for (u=j;u<=j+k;u++)
                {
                    x=i;
                    y=i+k;
                    while (x<=y)
                    {
                        if (a[x][u]!=a[y][u]) 
                        {
                            bj=false;
                            break;
                        }
                        x++;
                        y--;
                    }
                    if (bj==false) break;
                }
                if (bj==true) ans=max(ans,k+1);
            }
    printf("%d\n",ans);
    fclose(stdin);
    fclose(stdout);
    return 0;
}

你可能感兴趣的:(信息学总结)