题目
n*n(n<=1e3)的全小写字母矩阵,求图中的最大对称子矩阵的边长
其中对称子矩阵的对角线是从右上角到左下角
bca
ebd
ghi
如上例,以ce为轴,应当输出2
题解
kuangbin的基础dp,软磨硬泡总算刷完了
枚举每个点,把每个点当左下角来看,dp[i][j]从其右上的dp[i-1][j+1]来转移,
转移时,暴力判断本列上分和本行右边能不能扩展,
如果能扩展到对应位置,就是右上的子矩阵规模+1
O(n^3)没敢莽,但赛后暴力了一下n=1e3的全a矩阵,计算量约在3e8,5s足矣
代码
#include<iostream>
#include<cstdio>
#include<vector>
#include<cstring>
using namespace std;
const int N=1e3+10;
char s[N][N];
int n,dp[N][N];
//复杂度在最坏情况下O(n^3)
//1e3个全a字母 计算量约在3e8 单组样例可以接受
//计算次数最坏情况下约为(2*n-1)*1+(2*(n-1)-1)*2+...+(2*1-1)*n
//敢写敢过 榜上一片过时 先冲一发朴素想法
int main()
{
while(~scanf("%d",&n)&&n)
{
for(int i=0;i<n;++i)
scanf("%s",s[i]);
int ans=1;
//从右上角起 向左dp 向下dp
for(int i=0;i<n;++i)
{
for(int j=n-1;j>=0;--j)
{
dp[i][j]=1;
if(i==0||j==n-1)continue;
int mx=dp[i-1][j+1];
//暴力比较[i][j] 该列内该位置以上 和 该行内该位置以右
for(int k=1;k<=mx;++k)
{
if(s[i-k][j]==s[i][j+k])dp[i][j]++;
else break;
}
ans=max(ans,dp[i][j]);
}
}
printf("%d\n",ans);
}
return 0;
}