HDU 2203 亲和串(简单KMP,不过需要预判断)

亲和串

Time Limit: 3000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 6047    Accepted Submission(s): 2738


Problem Description
人随着岁数的增长是越大越聪明还是越大越笨,这是一个值得全世界科学家思考的问题,同样的问题Eddy也一直在思考,因为他在很小的时候就知道亲和串如何判断了,但是发现,现在长大了却不知道怎么去判断亲和串了,于是他只好又再一次来请教聪明且乐于助人的你来解决这个问题。
亲和串的定义是这样的:给定两个字符串s1和s2,如果能通过s1循环移位,使s2包含在s1中,那么我们就说s2 是s1的亲和串。
 

Input
本题有多组测试数据,每组数据的第一行包含输入字符串s1,第二行包含输入字符串s2,s1与s2的长度均小于100000。
 

Output
如果s2是s1的亲和串,则输出"yes",反之,输出"no"。每组测试的输出占一行。
 

Sample Input
   
   
   
   
AABCD CDAA ASD ASDF
 

Sample Output
   
   
   
   
yes no
 

                     
            题目大意:第一串如果循环移位,把前面的移到后面去,可以含住第二串的话,输出yes,否则输出no

            解题思路:把第一串复制待会儿匹配用,标准KMP.

            题目地址:亲和串

AC代码:
#include<iostream>
#include<string>
#include<cstring>
#include<cstdio>
using namespace std;
char s1[100005],s2[100005],s[200005];
int next[100005],len1,len2,len;

void getnext()    //s2是模式串
{
     int i,j;
     next[0]=0,next[1]=0;
     for(i=1;i<len2;i++)
     {
          j=next[i];
          while(j&&s2[i]!=s2[j])
               j=next[j];
          if(s2[i]==s2[j])
               next[i+1]=j+1;
           else
               next[i+1]=0;
     }
}

int KMP()
{
     int i,j=0;
     for(i=0;i<len;i++)
     {
          while(j&&s[i]!=s2[j])
               j=next[j];
          if(s[i]==s2[j])
               j++;
          if(j==len2)
            return 1;
     }
     return 0;
}

int main()
{
    while(~scanf("%s%s",s1,s2))
    {
         len1=strlen(s1);
         len2=strlen(s2);
         len=2*len1;
         strcpy(s,s1);
         strcat(s,s1);   //把s1复制成两倍存在s3中
         getnext();
         if(KMP())
            puts("yes");
           else
               puts("no");
    }
}


          

你可能感兴趣的:(KMP,HDU)