字串乘方、字首中的週期(KMP)
總時間限制: 3000ms
記憶體限制: 65536kB
描述
給定兩個字串a和b,我們定義ab為他們的連線。例如,如果a=”abc”
而b=”def”, 則ab=”abcdef”。
如果我們將連線考慮成乘法,一個非負整數的乘方將用一種通常的方式定義:a0=””(空字串),a(n+1)=a*(a^n)。
輸入
每一個測試樣例是一行可列印的字元作為輸入,用s表示。s的長度至少為1,且不會超過一百萬。最後的測試樣例後面將是一個點號作為一行。
輸出
對於每一個s,你應該列印最大的n,使得存在一個a,讓s=a^n
樣例輸入
abcd
aaaa
ababab .樣例輸出
1
4
3
提示
本問題輸入量很大,請用scanf代替cin,從而避免超時。
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
const int MAXM = 1000005;
char P[MAXM];
int N[MAXM];
int m;
int main()
{
while (scanf("%s", P) == 1) {
if ((m = strlen(P)) == 1 && P[0] == '.')
break;
int j = 0, t = N[0] = -1;
while (j < m) {
if (t == -1 || P[t] == P[j])
N[++j] = ++t;
else
t = N[t];
}
int len = m - t;
printf("%d\n", m % len ? 1 : m / len);
}
system("pause");
return 0;
}
總時間限制: 3000ms 記憶體限制: 65536kB
描述
一個字串的字首是從第一個字元開始的連續若干個字元,例如"abaab"共有5個字首,分別是a, ab, aba, abaa, abaab。
我們希望知道一個N位字串S的字首是否具有迴圈節。換言之,對於每一個從頭開始的長度為 i (i 大於1)的字首,是否由重複出現的子串A組成,即 AAA…A (A重複出現K次,K 大於 1)。如果存在,請找出最短的迴圈節對應的K值(也就是這個字首串的所有可能重複節中,最大的K值)。
輸入
輸入包括多組測試資料。每組測試資料包括兩行。
第一行包括字串S的長度N(2 <= N <= 1 000 000)。
第二行包括字串S。
輸入資料以只包括一個0的行作為結尾。
輸出
對於每組測試資料,第一行輸出 "Test case #“ 和測試資料的編號。
接下來的每一行,輸出字首長度i和重複測數K,中間用一個空格隔開。字首長度需要升序排列。
在每組測試資料的最後輸出一個空行。
樣例輸入
3
aaa
12
aabaabaabaab
0
樣例輸出
Test case #1
2 2
3 3
Test case #2
2 2
6 2
9 3
12 4
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
const int MAXN = 1000005;
int N[MAXN], n;
char s[MAXN];
int main()
{
int cnt = 0;
while (cin >> n) {
if (n == 0)
break;
printf("Test case #%d\n", ++cnt);
scanf("%s", s);
n = strlen(s);
int j = 0, t = N[0] = -1;
while (j < n) {
if (t == -1 || s[j] == s[t]) {
N[++j] = ++t;
int len = j - t;
if (j % len == 0 && len != j)
printf("%d %d\n", j, j/len);
}
else
t = N[t];
}
printf("\n");
}
system("pause");
return 0;
}