题意是说循环扫描母串A(意思就是可以重复遍历很多次),如果子串B存在于循环的母串之中,那么输出yes,否则no。
嗯,注意一点:如果串B的长度大于了串A是不行的,因为按照题意所说的子串是包含在母串中的,所以如果串B的长度超过了串A,输出应该是no。
并且很容易就会发现只要两个母串就能够表示出所有可能的子串了。
另外,母串ABCD,子串ABCDA,这样子串长度是超过母串了的,尽管母串重复之后为ABCDABCD包含ABCDA,仍应该输出no。
代码如下:
#include <cstdio> #include <cmath> #include <cstring> #include <ctime> #include <iostream> #include <algorithm> #include <set> #include <vector> #include <sstream> #include <queue> #include <typeinfo> #include <fstream> #include <map> #include <stack> typedef long long LL; using namespace std; const int MAX = 200002; int kmp_next[MAX]; void k_next (char *s) { int len = strlen(s); kmp_next[0] = -1; int k = -1; //front int j = 0; // behind while (j < len) { if (k == -1 || kmp_next[k] == kmp_next[j]) { ++k; ++j; if (kmp_next[k] != kmp_next[j]) kmp_next[j] = k; else kmp_next[j] = kmp_next[k]; } else // shipei k = kmp_next[k]; } return; } bool k_match(char *s, char *b) { int slen = strlen(s); int blen = strlen(b); int i = 0; int j = 0; while (i < slen && j < blen) { if (j == -1 || s[i] == b[j]) { ++i; ++j; } else j = kmp_next[j]; } if (j == blen) return true; else return false; } int main() { char a[MAX], b[MAX]; char s[MAX]; while (~scanf("%s %s", a, b)) { strcpy(s, a); strcat(s, a); if (strlen(a) < strlen(b)) { printf("no\n"); continue; } k_next(b); if (k_match(s, b)) printf("yes\n"); else printf("no\n"); } return 0; }