1. 程式人生 > >hdu 2203 親和串 (KMP)

hdu 2203 親和串 (KMP)

size mat 世界 math != mis bsp The others

親和串
Time Limit: 3000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 17936 Accepted Submission(s): 7896
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

C/C++:

 1 #include <map>
 2 #include <queue>
 3 #include <cmath>
 4 #include <vector>
 5 #include <string>
 6 #include <cstdio>
 7 #include <cstring>
 8 #include <climits>
 9 #include <iostream>
10 #include <algorithm>
11 #define INF 0x3f3f3f3f
12
using namespace std; 13 const int my_max = 1e5 + 10; 14 15 string s1, s2; 16 int my_next[my_max]; 17 18 bool my_kmp() 19 { 20 int len1 = s1.size(), len2 = s2.size(), temp = len2; 21 if (len1 < len2) return false; 22 for (int i = 1, j = 0; i < len2; ++ i) 23 { 24 while (j > 0
&& s2[i] != s2[j]) j = my_next[j]; 25 if (s2[i] == s2[j]) ++ j; 26 my_next[i + 1] = j; 27 } 28 29 for (int i = 0, j = 0; i < len1; ++ i) 30 { 31 while (j > 0 && s2[j] != s1[i]) j = my_next[j]; 32 if (s2[j] == s1[i]) ++ j; 33 if (j == len2) return true; 34 } 35 36 return false; 37 } 38 39 int main() 40 { 41 ios::sync_with_stdio(false); 42 memset(my_next, 0, sizeof(my_next)); 43 while (cin >>s1) 44 { 45 cin >>s2; 46 if (s1.size() < s2.size()) 47 { 48 printf("no\n"); 49 continue; 50 } 51 s1 = s1 + s1.substr(0, s1.size() - 1); 52 53 if (my_kmp()) printf("yes\n"); 54 else printf("no\n"); 55 } 56 return 0; 57 }

hdu 2203 親和串 (KMP)