kuangbin专题16D(next求最小循环节)

题目链接: https://vjudge.net/contest/70325#problem/D

 

题意: 给出一个循环字符串, 可以在两端添加任意字符, 问最少添加多少字符可以使循环字符串变成周期循环字符串且周期数大于1.

 

思路:  gel = n - next[n] 为该字符串的最小循环节. 证明见: http://www.cnblogs.com/wuyiqi/archive/2012/01/06/2314078.html

                            : http://www.cnblogs.com/jackge/archive/2013/01/05/2846006.html

那么当 next[n] = 0 时, 需要再添加 n 个字符,

当 next[n] != 0 且 n % gel = 0 时不需要添加字符,

其他情况则需添加 gel - n % gel 个字符.

 

代码:

 1 #include <iostream>
 2 #include <stdio.h>
 3 #include <string.h>
 4 using namespace std;
 5 
 6 const int MAXN = 1e5 + 10;
 7 int nxt[MAXN], n;
 8 char s[MAXN];
 9 
10 void get_nxt(void){
11     memset(nxt, 0, sizeof(nxt));
12     int j = -1, i = 0;
13     nxt[0] = -1;
14     while(i < n){
15         if(j == -1 || s[i] == s[j]){
16             i++;
17             j++;
18             nxt[i] = j;
19         }else j = nxt[j];
20     }
21 }
22 
23 int main(void){
24     int t, sol;
25     scanf("%d", &t);
26     while(t--){
27         scanf("%s", s);
28         n = strlen(s);
29         get_nxt();
30         int cnt = n - nxt[n];
31         if(cnt == n) sol = n;
32         else if(n % cnt == 0) sol = 0;
33         else sol = cnt - n % cnt;
34         printf("%d\n", sol);
35     }
36     return 0;
37 }
View Code

 

posted @ 2017-08-10 11:29  geloutingyu  阅读(194)  评论(0编辑  收藏  举报