1616: 最长回文串
Time Limit: 1 Sec Memory Limit: 128 MB
Submit: 144 Solved: 113
[Submit][Status][Web Board]
Description
求一个字符串的最长回文串
Input
第一行输入n
接下来n行每行每行一个字符串长度<=100000
Output
输出最长回文串的长度
Sample Input
3 abababa aaaabaa acacdas
Sample Output
7 5 3
HINT
不要想太多 Water
【分析】到最后才看到hint的“不要想太多Water”。。so!!!一般方法就好啦!!根本不用考虑效率的问题啊!!水题一道了。。
然后注意判断是否回文串的时候的下标s[i+j-k]:因为这段区间为i~j,中点为(i+j)/2,所以s[k]对应的点就是(i+j)/2-k+(i+j)/2=i+j-k啦~
#include<bits/stdc++.h>
using namespace std;
char s[100010];
int main()
{
int n;
scanf("%d",&n);
while(n--)
{
memset(s,0,sizeof(s));
scanf("%s",s);
int len=strlen(s);
int max=0;
for(int i=0;i<len;i++)
for(int j=i;j<len;j++)
{
int ok=1;
for(int k=i;k<=j;k++)//套了3个循环还是木有超时hhh
if(s[k]!=s[i+j-k])ok=0;
if(ok&&j-i+1>max)max=j-i+1;//更新max
}
cout<<max<<endl;
}
return 0;
}
方法二:枚举回文串的中间位置i,然后不断往外扩展直到有字符串不同。并且长度为奇数和偶数的方式有点区别的。
扫描二维码关注公众号,回复:
2795580 查看本文章
注释掉的部分是用于记录回文串开始和结束的地方。
#include<bits/stdc++.h>
using namespace std;
char s[100010];
int main()
{
int n;
scanf("%d",&n);
while(n--)
{
memset(s,0,sizeof(s));
scanf("%s",s);
int len=strlen(s);
int max=0;
for(int i=0;i<len;i++)
{ for(int j=0;i-j>=0&&i+j<len;j++)
{
if(s[i-j]!=s[i+j])break;
if(j*2+1>max){
max=j*2+1;
// x=p[i-j];
// y=p[i+j];
}
}
for(int j=0;i-j>=0&&i+j+1<len;j++)
{
if(s[i-j]!=s[i+j+1])break;
if(j*2+2>max){
max=j*2+2;
// x=p[i-j];
// y=p[i+j+1];
}
}
}cout<<max<<endl;
}
return 0;
}