題解 P4544 【[USACO10NOV]Buying Feed G】
阿新 • • 發佈:2020-12-29
第一遍讀完這道題,這不就是個裸的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; }//求next 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; }