Problem Description
人随着岁数的增长是越大越聪明还是越大越笨,这是一个值得全世界科学家思考的问题,同样的问题Eddy也一直在思考,因为他在很小的时候就知道亲和串如何 判断了,但是发现,现在长大了却不知道怎么去判断亲和串了,于是他只好又再一次来请教聪明且乐于助人的你来解决这个问题。
亲和串的定义是这样的:给定两个字符串s1和s2,如果能通过s1循环移位,使s2包含在s1中,那么我们就说s2 是s1的亲和串。
亲和串的定义是这样的:给定两个字符串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
题解:
我们分析一下,字符串只有可能是两边有一点,中间循序或者只有这三部分的一或两部分,不过无论是那种,我们把字符串复制
到大于另一个串,再多复制一次,那么一定是多包括所有的串的,然后跑一遍KMP就可以了。
代码:
#include<iostream> #include<stdio.h> #include<stdlib.h> #include<algorithm> #include<cstring> using namespace std; char x[100100],y[100100]; char xx[1000000]; int f[1000000]; int main(){ while(scanf("%s",&x)!=EOF){ scanf("%s",&y); memset(f,0,sizeof(f)); memset(xx,0,sizeof(xx)); int len1=strlen(x),len2=strlen(y),len3=len1; while(len1<len2){ len1+=len1; } len1+=len1; for(int i=0;i<len1;i++){ xx[i]=x[i%len3]; } f[0]=f[1]=0; for(int i=1;i<len2;i++){ int j=f[i]; while(j&&y[j]!=y[i]) j=f[j]; if(y[j]==y[i]) f[i+1]=j+1; else f[j]=0; } int j=0,flag=1; for(int i=0;i<len1;i++){ while(j&&xx[i]!=y[j]) j=f[j]; if(xx[i]==y[j]) j++; if(j==len2) { printf("yes "); flag=0; break; } } if(flag){ printf("no "); } } }