Language:
Period
Description
求一个字符串中,所有循环节大于2的子串。
Input
有若干组数据,
每组数据第一行为字符串长度,第二行为字符串
以0结束。
Output
对于每组数据,输出'Test case #i",i从0开始,之后每行输出两个数,分别表示前缀长度和循环节数(>1).
每组数据后输出一个空行。
Sample Input 3 aaa 12 aabaabaabaab 0 Sample Output Test case #1 2 2 3 3 Test case #2 2 2 6 2 9 3 12 4 Source |
还是Next,
先做不判重复优化的处理
观察发现若前面有循环节,则有i->i-p->i-2p...->i-kp=1
则i-next[i]表示循环结长度p,显然有p|(i-1),(i-1) div p>1.
如下:
Program Poj1961;
const
maxn=10000000;
var
i,j,tt,n,duan_luo:longint;
next:array[1..maxn] of longint;
a:ansistring;
begin
tt:=1;
while (true) do
begin
readln(n);
if n=0 then break;
readln(a); inc(n); a:=a+'.';
i:=1;j:=0;next[1]:=0;
while (i<=n-1) do
begin
if (j=0) or (a[i]=a[j]) then
begin
inc(i);inc(j);
// if (a[i]<>a[j]) then next[i]:=j else next[i]:=next[j];
next[i]:=j;
end
else j:=next[j];
end;
writeln('Test case #',tt);
for i:=2 to n do
begin
duan_luo:=i-next[i];
if (duan_luo>0) and ((i-1) mod duan_luo=0) and ((i-1) div duan_luo>1) then
writeln(i-1,' ',(i-1) div duan_luo);
end;
// readln;
writeln;
inc(tt);
end;
end.