回文串
思路
这道题我先写了马拉车(不会的可以去学一学,能以O(n)复杂度求最长回文串长度),A了之后看数据范围,发现暴力也是能过的。需要注意点一些细节:(我被坑过的点)
马拉车记得在要在字符串前面加多一个字符防止越界。
暴力算法不要列举区间再判断是否回文,先列举中心点再求回文长度更快。同时注意字符串长度的奇偶性。
暴力代码
#include<bits/stdc++.h> using namespace std; int main() { char s[1205]; while(scanf("%s",s)!=EOF){ int len=strlen(s),maxx=0; for(int i=0;i<len;i++){ int len2=1,len3=0; while(i-len2>=0&&i+len2<len&&s[i-len2]==s[i+len2]) len2++; while(i-len3>=0&&i+1+len3<len&&s[i-len3]==s[i+1+len3]) len3++; maxx=max(maxx,max(len2*2-1,len3*2)); } cout<<maxx<<endl; } return 0; }
Manacher代码
#include<bits/stdc++.h> using namespace std; int len[3000],len2; int manacher(char str[],int len2){ int mx=0,id=0,maxx=0; for(int i=1;i<len2;i++){ if(mx>i) len[i]=min(len[2*id-i],mx-i); else len[i]=1; while(str[i-len[i]]==str[i+len[i]]) len[i]++; if(i+len[i]>mx){ id=i; mx=i+len[i]; } maxx=max(len[i],maxx); } return maxx-1; } int main(){ char s[1200]; while(scanf("%s",s)!=EOF){ char str[3000]; memset(len,0,sizeof(len)); str[0]='$'; str[1]='#'; len2=1; for(int i=0;i<strlen(s);i++){ str[++len2]=s[i]; str[++len2]='#'; } str[len2+1]=0; printf("%d\n",manacher(str,len2)); } return 0; }