湖大 11404 manacher
链接 http://acm.hunnu.edu.cn/online/?action=problem&type=show&id=11404&courseid=0
求 最长回文个数 并且输出 ; 虽然 O(n^2) 可过; 但 O(n) 是王道
看这个博客 http://www.cnblogs.com/wulangzhou/p/3449428.html
1 #include<iostream> 2 #include<stdio.h> 3 #include<algorithm> 4 #include<cstring> 5 #include<cmath> 6 #define maxn 111000 7 using namespace std; 8 inline int min( int a,int b ){return a>b?b:a;} 9 inline int max( int a,int b ){return a>b?a:b;} 10 char cha[maxn],str[maxn*2]; int pi[maxn*2]; 11 struct date{ 12 int l,r,len; 13 bool operator <(const date &a)const{ 14 if( a.len != len )return a.len < len; 15 else return a.r < r; 16 } 17 }node[112345]; 18 void manacher( ) 19 { 20 int len = strlen( str ); int mx = 0; int id = 0; 21 memset( pi,0,sizeof(pi) ); 22 for( int i = 0; i < len; i++ ) 23 { 24 if( mx > i )pi[i] = min( pi[id*2-i],mx-i ); 25 else pi[i] = 1; 26 while( str[i-pi[i]] == str[i+pi[i]] )pi[i]++; 27 node[i].l = i-(pi[i]-1); node[i].r = i+(pi[i]-1); node[i].len = node[i].r - node[i].l + 1; 28 if( i+pi[i] > mx ) 29 { 30 mx = i+pi[i]; 31 id = i; 32 } 33 } 34 } 35 int main( ) 36 { 37 int T,cas = 1; scanf("%d",&T); 38 while( T-- ) 39 { 40 scanf("%s",&cha); int len = strlen( cha ); int k = 0; str[k++] = '!'; 41 for( int i = 0; i < len; i++ ) 42 str[k++] = '#',str[k++] = cha[i]; str[k++] = '#'; str[k] = '\0'; 43 manacher( ); 44 printf("Case #%d:\n",cas++); 45 sort( node,node+k ); len = node[0].len; 46 if( len <= 3 ){continue;} 47 for( int i = 0; i < k; i++ ) 48 if( node[i].len == len ) 49 { 50 for( int j = node[i].l; j <= node[i].r; j++ ) 51 if( str[j] != '#' )cout<<str[j]; 52 cout<<endl; 53 }else break; 54 } 55 return 0; 56 }
#include<iostream> #include<stdio.h> #include<cstring> #include<algorithm> #include<cmath> using namespace std; char str[2100],cha[2100]; int tab[2100]; void manacher( ) { int Mx = 0; int id = 0; int len = strlen(cha); memset(tab,0,sizeof(tab)); for( int i = 1; i < len; i++ ) { if( i < Mx ) tab[i] = min( tab[id*2-i],Mx-i ); else tab[i] = 1; while( cha[i+tab[i]] == cha[i-tab[i]] )tab[i]++; tab[i]--; if( Mx < i+tab[i] ){ Mx = i+tab[i]; id = i; } } } int main( ) { int T,cas = 1; cin>>T; while( T-- ) { scanf("%s",&str); int len = strlen(str); int k = 0; cha[k++] = '@'; for( int i = 0; i < len; i++ ) {cha[k++] = '#', cha[k++] = str[i];} cha[k++] = '#'; cha[k] = '\0'; int Max = 0; manacher( ); printf("Case #%d:\n",cas++); for( int i = 1; i < k; i++ ) if( cha[i] != '#' )Max = max( Max,(tab[i]/2)*2+1 ); else Max = max( Max,tab[i] ); if( Max <= 1 ){continue;} for( int j = k-1; j >= 0; j-- ) { if( (cha[j] == '#'&&tab[j]==Max) || (cha[j] != '#'&&(tab[j]/2)*2+1 == Max ) ) for( int i = j-tab[j]; i != j+tab[j]; i++ ) if( cha[i] != '#' )cout<<cha[i]; cout<<endl; } } return 0; } /* abacaba */