HDU 3294(manacher模版题)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3294
题意:给定一个字符和一个字符串,求转化后字符串出现的第一个最长回文(即有很多相同长度,输出第一个),并输出起始终点位置,以及转化后的回文串。
题解:manacher算法求得最长回文串的长度mxx以及该回文串的中心位置iid,则s[iid-mxx+1]~s[iid+mxx-1]中去掉#的就是所求串,原位置为(iid-mxx+1)/2-1~(iid+mxx-1)/2-1.
代码如下:
1 #include<iostream> 2 #include<cstdio> 3 #include<algorithm> 4 #include<cstring> 5 using namespace std; 6 const int maxn =200000+50; 7 char s[maxn<<1]; 8 int p[maxn<<1]; 9 int mxx,iid; 10 void manacher() 11 { 12 mxx=-1; 13 int len=strlen(s); 14 for(int i=len;i>=0;i--) 15 { 16 s[i+i+2] = s[i]; 17 s[i+i+1] = '#'; 18 } 19 s[0] = '*'; 20 int id,mx=0; 21 for(int i=1;i<len+len+2;i++) 22 { 23 if(mx>1) p[i] = min(p[2*id-i],mx-i); 24 if(p[i]==0) p[i]=1; 25 while(s[i-p[i]]==s[i+p[i]])p[i]++; 26 if(i+p[i]>mx) 27 { 28 mx=i+p[i]; 29 id=i; 30 } 31 if(p[i]-1>mxx) 32 { 33 mxx=p[i]-1; 34 iid=i; 35 } 36 } 37 } 38 39 int main() 40 { 41 char c; 42 while(~scanf("%c%s",&c,s)) 43 { 44 getchar(); 45 int k = c-'a'; 46 int len=strlen(s); 47 48 for(int i=0;i<len;i++) 49 { 50 s[i]-=k; 51 if(s[i]<'a') 52 s[i]+=('z'-'a'+1); 53 } 54 manacher(); 55 if(mxx==1) 56 printf("No solution!\n"); 57 else 58 { 59 printf("%d %d\n",(iid-mxx+1)/2-1,(iid+mxx-1)/2-1); 60 for(int i=(iid-mxx+1);i<=(iid+mxx-1);i++) 61 if(s[i]!='#'&&s[i]!='*') 62 printf("%c",s[i]); 63 printf("\n"); 64 } 65 } 66 }
浙公网安备 33010602011771号