题目链接:Cyclic Nacklace
题目大意:
给定一个字符串,只能在该字符串最左端和最右端增加字符,最少增加多少个字符可以使得该字符串可以由其中一个字串循环得到
思路:
题目既然要求最后得到的字符串可以由其字串循环得到,而且只能在左边和右边增加字符,很明显就是字符串的最小循环节问题
首先利用KMP算法求得原字符串的next数组
因为i - next[i]为以第i个字符结尾的字符串的最小循环节长度
假定题目给定的字符串长度为n, 那么该字符串的最小循环节长度 k = n - next[n]
我们对最小循环节进行判断即可找到答案
- 如果k == n 说明字符串本身是最小循环节,那么我们只能再增加n个字符才能构成循环
- 如果k != n,并且n % k == 0说明整个字符串由长度为k的循环节循环构成,这时候不需要增加字符就能构成循环
- 如果k != n,并且n % k != 0 说明需要再增加k - n % k个字符才能使整个字符串构成循环
代码如下:
string s;
int ne[N];
inline void get_next()
{
int i = 0, j = -1;
ne[0] = -1;
while (i < s.size())
{
if (j == -1 || s[i] == s[j])
{
i ++, j ++ ;
ne[i] = j;
}
else j = ne[j];
}
}
int main()
{
IOS;
int T; cin >> T;
while (T -- )
{
cin >> s;
get_next();
int ans = 0, n = s.size();
int k = n - ne[n];
if (k == n) cout << n << "\n";
else if (n % k == 0) cout << "0\n";
else cout << k - n % k << "\n";
}
return 0;
}