不要想复杂
数组下标设为1开始
证明算法正确性:if + only if 充分+必要
输出格式,空行空格
特殊情况:全相等
数组作为参数传入函数 若指针传入,只传入第一个地址,不传长度,可用[]运算符,但不能strlen求长度。需单独传入长度length;或拷贝传入 char a[]
思路:
p[x]表示x长度的前缀的最短循环节的长度 aabaab,p[1]=0,p[2]=1,p[3]=3,p[6]=3
利用next数组,如果next[i]==i-1,则之前全相等,特例,p[i]=0;如果s[next[i]]==s[i] && i-next[i]==p[next[i]],next-i之前以及next-i到i之间均构成整数个循环节,next-i到i之间元素和循环节相等,则i的最小循环节长度和next-i的相等
i/next[i]=循环次数k
#include<iostream>
#include<string>
#include<cstring>
using namespace std;
char s[1000000 + 10] = { 0 };
long long nex[1000000 + 10] = { 0 };
long long p[1000000 + 10] = { 0 };
void get_next(long long *na, char *sa, long long len) {
long long j = 1, k = 0;
na[1] = 0;
while (j < len) {
if (k == 0 || sa[k] == sa[j]) na[++j] = ++k;
else k = na[k];
}
}
void clear() {
memset(s, 0, sizeof(s));
memset(nex, 0, sizeof(nex));
memset(p, 0, sizeof(p));
}
int main() {
long long n, T = 1;
cin >> n;
while (n != 0) {
string input;
cin >> input;
for (long long i = 1; i <= n; i++) {
s[i] = input[i - 1];
}
get_next(nex, s, n);
p[1] = 0;
cout << "Test case #" << T++ << endl;
for (long long i = 2; i <= n; i++) {
if (nex[i] == i - 1) {
if (s[i] == s[i - 1]) {
p[i] = 0;
cout << i << " " << i << endl;
}
else {
p[i] = i;
}
}
else if (s[nex[i]] == s[i]) {
if (i - nex[i] == p[nex[i]]) {
p[i] = p[nex[i]];
cout << i << " " << i / p[i] << endl;
}
else p[i] = i;
}
else p[i] = i;
}
cout << "\n";
cin >> n;
clear();
}
return 0;
}