HDU 2203 親和串 kmp演算法
阿新 • • 發佈:2018-12-31
題意:
Problem Description 人隨著歲數的增長是越大越聰明還是越大越笨,這是一個值得全世界科學家思考的問題,同樣的問題Eddy也一直在思考,因為他在很小的時候就知道親和串如何判斷了,但是發現,現在長大了卻不知道怎麼去判斷親和串了,於是他只好又再一次來請教聰明且樂於助人的你來解決這個問題。親和串的定義是這樣的:給定兩個字串s1和s2,如果能通過s1迴圈移位,使s2包含在s1中,那麼我們就說s2 是s1的親和串。
Input 本題有多組測試資料,每組資料的第一行包含輸入字串s1,第二行包含輸入字串s2,s1與s2的長度均小於100000。
Output 如果s2是s1的親和串,則輸出"yes",反之,輸出"no"。每組測試的輸出佔一行。
思路:首先把目標串複製一份拼接到自己後面,然後直接kmp去匹配
#include <iostream> #include <cstdio> #include <cstring> #include <algorithm> using namespace std; const int N = 100010; char s1[N*2], s2[N]; int nt[N]; void getnt() { int i = 0, j = - 1; nt[0] = -1; while(s2[i]) { if(j == -1 || s2[i] == s2[j]) { i++, j++; if(s2[i] != s2[j]) nt[i] = j; else nt[i] = nt[j]; } else j = nt[j]; } } bool kmp() { getnt(); int i = 0, j = 0; while(s1[i]) { if(j == -1 || s1[i] == s2[j]) i++, j++; else j = nt[j]; if(j != -1 && !s2[j]) return true; } return false; } int main() { while(~ scanf("%s", s1)) { scanf("%s", s2); int len = strlen(s1); for(int i = len; i < len * 2; i++) s1[i] = s1[i-len]; s1[len*2] = '\0'; if(kmp()) printf("yes\n"); else printf("no\n"); } return 0; }