描述
回文序列是指左右对称的序列。例如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 n∗m的矩阵内找到一个最大的 p ∗ p p*p p∗p的子矩阵使得该子矩阵内的每行每列都是回文
输出 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(n∗m∗min(n,m))
暴力判断是 O ( n 2 ∗ m 2 4 ) O(\dfrac{n^2*m^2}{4}) O(4n2∗m2)
所以说总的时间复杂度就是 O ( n 3 ∗ m 3 ∗ m i n ( n , m ) 4 ) O(\dfrac{n^3*m^3*min(n,m)}{4}) O(4n3∗m3∗min(n,m))
按理说 n , m ≤ 300 n,m≤300 n,m≤300过不去的
但数据太水就过去了QAQ
#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;
}