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
本题的关键:
s2可以循环移位是本题的关键,可以在s1的后面接上s1的前strlen(s2)个字符,然后这就变成了普通的字符串查找了。
做法一:用函数strstr查找 用时15ms
1 #include<iostream> 2 #include<cstring> 3 #include<cstdio> 4 using namespace std; 5 #define N 100005 6 char s1[2*N]; 7 char s2[N]; 8 int len1; 9 int len2; 10 int main() 11 { 12 while(scanf("%s",s1)!=EOF) 13 { 14 scanf("%s",s2); 15 len1=strlen(s1); 16 len2=strlen(s2); 17 if(len1<len2) 18 { 19 cout<<"no"<<endl; 20 continue; 21 } 22 int i,j; 23 for(i=len1,j=0;i<len1+len2;i++) 24 { 25 s1[i]=s1[j++]; 26 } 27 if(strstr(s1,s2)!=NULL) 28 cout<<"yes"<<endl; 29 else 30 cout<<"no"<<endl; 31 } 32 return 0; 33 }
做法二:kmp 用时0ms
1 #include<iostream> 2 #include<cstring> 3 #include<cstdio> 4 using namespace std; 5 #define N 100005 6 char s1[2*N]; 7 char s[N]; 8 char s2[N]; 9 char next[N]; 10 int len1,len2; 11 void get_next() 12 { 13 int i=0,j=-1; 14 next[0]=-1; 15 while(i<len2) 16 { 17 if(j==-1||s2[i]==s2[j]) 18 { 19 i++;j++; 20 next[i]=j; 21 } 22 else 23 j=next[j]; 24 } 25 } 26 void KMP() 27 { 28 int i=0,j=0; 29 get_next(); 30 while(i<len1&&j<len2) 31 { 32 if(j==-1||s1[i]==s2[j]) 33 { 34 i++; 35 j++; 36 } 37 else 38 j=next[j]; 39 } 40 if(j==len2) 41 { 42 cout<<"yes"<<endl; 43 return ; 44 } 45 46 cout<<"no"<<endl; 47 return ; 48 } 49 50 51 int main() 52 { 53 while(scanf("%s%s",s1,s2)!=EOF) 54 { 55 len1=strlen(s1); 56 len2=strlen(s2); 57 if(len1<len2) 58 { 59 printf("no\n"); 60 continue; 61 } 62 strcpy(s,s1); 63 strcat(s1,s); 64 len1=len1+len2; 65 memset(next,-1,sizeof(next)); 66 KMP(); 67 } 68 return 0; 69 }