【佛山市选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)的矩阵内找到一个最大的(p*p)的子矩阵使得该子矩阵内的每行每列都是回文
输出(p)
分析
这种题嘛
想打(manacher)也没问题,反正我是不会 (有巨佬(manacher+dp))
所以我就打暴力
枚举起点和(p)
然后暴力判断是否合法
算一下之间复杂度
枚举起点和(p)是(O(n*m*min(n,m)))
暴力判断是(O(dfrac{n^2*m^2}{4}))
所以说总的时间复杂度就是(O(dfrac{n^3*m^3*min(n,m)}{4}))
按理说(n,m≤300)过不去的
但数据太水就过去了QAQ
Code
#include<cstdio>
#include<iostream>
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
",ans);
fclose(stdin);
fclose(stdout);
return 0;
}