描述
给定一个仅由小写字母组成的长度不超过1e6的字符串,将首字母移动到末尾并记录所得的字符串,不断重复操作,虽然记录了无限个字符串,但其中不同的字符串数目是有限的,问不同的字符串有多少个?
输入:
abab
输出
2
解释:记录了 abab 和 baba两个不同的字符串
思路:
如果字符串中有循环的话,那么循环的部分是通过上面的操作不可能得到和原来不同的字符串的。于是问题转化为求字符串中的循环节。假设字符串长度了n,利用kmp的next数组求出的循环节长度为Next[n],那么我们去掉循环部分得到的答案为 len,这里还需要注意的是党 n%len == 0的时候 答案是 len ,否则答案是 n。比如 aabbaaa 这个样例 答案是 7
#include <cstring>
#include <iostream>
#include <set>
#include <string>
using namespace std;
const int maxn = 3e6+5;
int Next[maxn];
void getNext(string s)
{
int m = s.length();
Next[0] = -1;
int j = 0;
int k = -1;
while( j < m) {
if (k == -1 || s[j] == s[k])
Next[++j] = ++k;
else
k = Next[k];
}
}
int main()
{
int t;
cin >> t;
while(t--) {
int n;
cin >> n;
string s;
cin >> s;
memset(Next,0,sizeof(Next));
int len = s.length();
getNext(s);
int ans = len - Next[len];
//cout << Next[len] << endl;
if (len%ans == 0)
cout << ans << endl;
else
cout << len << endl;
}
return 0;
}