HDU 5340Three Palindromes

版权声明:如果转载,请注明出处。 https://blog.csdn.net/S_999999/article/details/89190034

Three Palindromes

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)
Total Submission(s): 2051    Accepted Submission(s): 733


 

Problem Description

Can we divided a given string S into three nonempty palindromes?

Input

First line contains a single integer T≤20 which denotes the number of test cases.

For each test case , there is an single line contains a string S which only consist of lowercase English letters.1≤|s|≤20000

Output

For each case, output the "Yes" or "No" in a single line.

Sample Input

 

2

abc

abaadada

Sample Output

 

Yes

No

题目大意:问一个字符串能否分成三个非空回文字符串。

解题思路:     

  

很牛逼15MS就过了,我也不理解为什么,求大佬指点。。。。。。

#include<iostream> 
#include<cstring> 
using namespace std; 
#define MAXN 20005 
int n;
char d[MAXN];
char st[MAXN*2];
int p[MAXN*2],begi[MAXN*2],tail[MAXN*2];
int len;
void manacher()
{
    int MaxId=0,id;
    for(int i=0; i<len; i++)
    {
        if(MaxId>i)
            p[i]=min(p[2*id-i],MaxId-i);
        else
            p[i]=1;
        while(st[i+p[i]]==st[i-p[i]])
            p[i]++;
 
        if(p[i]+i>MaxId)
        {
            id=i;
            MaxId=p[i]+i;
        }
        p[i] -= 1;
    }
}
 
int main()
{
    int T;
    scanf("%d",&T);
    while(T--){
        getchar();
        scanf("%s",d);
        int l = strlen(d);
        len = 0;
        st[len++] = '#';
        for(int i = 0; i < l; i++){
            st[len++] = d[i];
            st[len++] = '#';
        }
        st[len] = 0;
        manacher(); 
        int flag = 0;
        int pn =0 ,ln = 0;
        for(int i = 1; i < len - 1; i++)
        {
            if(i - p[i] == 0) begi[pn++]  = i;
            if(i + p[i] == len-1) tail[ln++] = i;
        }
        for(int i = 0; i < pn; i++){
            for(int j = 0; j<=ln - 1; j++){
                int s1 = begi[i] + p[begi[i]]+1 ,s2 = tail[j] - p[tail[j]]-1;
                if(s1 > s2)
                    break;
                int mid = (s1 + s2)/2;
                if(p[mid] >= mid-s1)
                {
                    flag = 1;
                    break;
                }
            }
            if(flag )
                break;
        }
        if(flag )
            printf("Yes\n");
        else
            printf("No\n");
    }
    return 0;
}

一般做法:

#include<iostream>
#include<cstring>
using namespace std;
char  str[20009],s[40009];
int   p[40009],ll[40009],rr[40009]; 
int   len = 0;
void  init( ){
      int l = strlen( str );
      s[0]='$';
      s[1]='#';
      len = 1 ;
      for( int i=0;i<l;i++){
           s[++len] = str[i];
           s[++len] = '#';
      }
      s[++len]='\0'; 
}
void manacher( ){
     init( );
     int id ,mx=0;
     for( int i=1;i<len;i++){
           if( i < mx )
               p[i] = min( p[id*2-i],mx-i); 
          else p[i] =1;
          while( s[ i - p[i] ] == s[ i + p[i]])
                 p[i]++;
          if( i + p[i] > mx){
                mx = i+p[i];
                id = i;
          } 
     }
}
int main(void){
    int T;
    scanf("%d",&T);
    while( T-- ){
        scanf("%s",str);
        manacher();   
        int l=-1,r=-1;    
        for( int i=2;i<len-1;i++){  
        //第一个字符串所有可能的半径
        // $#a#a#a#
        if(  p[i]   == i   ){  
             ll[++l] = p[i] ;  
        }   
         //第三个字符串所有可能的半径  
        if( i+p[i] == len ){ 
                  rr[++r] = p[i] ;
             }
        }
        //printf("%d  %d\n",l,r);
        //枚举所有的情况 
        bool f = false; 
        for( int i=0 ;i<=l;i++){ 
             int s = ll[i]*2 ;
             for( int j=0; j<=r ;j++){
             int e = len - rr[j]*2 ; 
             int mid = ( e+s ) /2;
             if( s > e  )
                 continue;
             if( p[mid] == 1 ) 
                 continue; 
             if( p[mid] > mid -  s  ){
                  f = true;
                  break;
             }
                    
            } 
           if( f ){
               break;
              }    
        }
        if( f ){
            printf("Yes\n");
        } 
        else printf("No\n"); 
    }
     return 0;
}

猜你喜欢

转载自blog.csdn.net/S_999999/article/details/89190034