湖大 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 }
View Code

 

#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
*/

  

 

 

posted on 2013-10-08 23:42  浪舟  阅读(212)  评论(0编辑  收藏  举报

导航