[POJ1961 Period]

[题目来源]:Southeastern Europe 2004

[关键字]:字符串

[题目大意]:给定一个字符串,求到哪一位时的字串是前几位循环组成的,并求出循环次数。

//=====================================================================================================

[分析]:利用KMP来求解。在KMP中有一个p数组记录当前字符的它的上一个位置,且保证这一段一定是来连续的。所以如果i处有循环则i到p[i]的长度即为循环节长度,所以如果i mod  (i-p[i])=0则说明有循环,i div (i-p[i])就是循环次数。

[代码]:

View Code
 1 var
2 n, tc: longint;
3 s: ansistring;
4 p: array[0..2000010] of longint;
5
6 procedure init;
7 var
8 i: longint;
9 begin
10 readln(n);
11 if n = 0 then halt;
12 s := '';
13 readln(s);
14 end;
15
16 procedure work;
17 var
18 i, k, temp: longint;
19 begin
20 fillchar(p,sizeof(p),0);
21 k := 0;
22 p[1] := 0;
23 for i := 2 to n do
24 begin
25 while (k > 0) and (s[i] <> s[k+1]) do k := p[k];
26 if s[i] = s[k+1] then inc(k);
27 p[i] := k;
28 end;
29 for i := 1 to n do
30 if p[i] <> 0 then
31 begin
32 temp := i-p[i];
33 if i mod temp = 0 then
34 writeln(i,'',i div temp);
35 end;
36 end;
37
38 begin
39 tc := 0;
40 while 1 = 1 do
41 begin
42 inc(tc);
43 init;
44 writeln('Test case #',tc);
45 work;
46 writeln;
47 end;
48 end.



你可能感兴趣的:(poj)