第一遍读完这道题,这不就是个裸的KMP板子吗,然后迅速打出了KMP,发现并过不了样例2,于是又仔细读了一下题,发现读漏了一个条件,即需要在中间也出现过,因为我们知道,KMP中的next数组存的是相同的前缀和后缀的长度,那么只需要找在中间出现过前缀长度,并标记一下就行了,最后在匹配的时候多判断一下。
详见代码
#include<iostream> #include<cstdio> using namespace std; const int N = 1e6 + 5;
string s; int net[N], num[N]; bool is[N];
int main() { cin >> s; for (int i = 1, j = 0; s[i]; i++) { while (j && s[i] != s[j]) j = net[j - 1]; if (s[i] == s[j]) j++; net[i] = j; } int len = s.length(); for (int i = 1, j = 0; i < len - 1; i++) { while (j && s[i] != s[j]) j = net[j - 1]; if (s[i] == s[j]) j++; is[j] = true; } int j = 0; for (int i = 0; i < len; i++) { while (j && s[i] != s[j]) j = net[j - 1]; if (s[i] == s[j]) j++; while (j && !is[j]) j = net[j - 1]; } if (!j) cout << "Just a legend"; else for (int i = 0; i < j; i++) cout << s[i]; return 0; }
|