题目链接:
http://codeforces.com/problemset/problem/182/D
题意:
求两个字符串公共循环节的个数
题解:
利用kmp算法中的next数组求出两个字符串的最小循环节, 设字符串的长度为len,如果len%(len - next[len]) == 0就有最小循环节,最小循环节 = 原字符串.substr(0,len - next[len]),如果不等于0最小循环节就是字符串本身。然后求两个字符串各自循环次数的最小公倍数即可。
AC代码:
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
string p,t;
int nxta[100050];
int nxtb[100050];
int m,mm,n,nn,result,k1,k2;
string s1,s2;
void getnext(string s, int nxt[])
{
int i = 0, j = -1;
nxt[0] = -1;
m = s.size();
while(i != m)
{
if(j == -1 || s[i] == s[j])
nxt[++i] = ++j;
else
j = nxt[j];
}
} //比较吊的
int gcd(int a, int b)
{
return b==0?a:gcd(b,a%b);
}
int main()
{
cin >> p;
cin >> t;
getnext(p,nxta);
getnext(t,nxtb);
nn = t.size();
mm = p.size();
s1 = p;
s2 = t;
if(mm % (mm - nxta[mm]) == 0)
{
int i = mm - nxta[mm];
s1 = p.substr(0, i);
}
if(nn % (nn - nxtb[nn]) == 0)
{
int i = nn - nxtb[nn];
s2 = t.substr(0, i);
}
if(s1 == s2)
{
k1 = s1.size();
k2 = s2.size();
int an1 = mm/k1;
int an2 = nn/k2;
int ii = gcd(an1,an2);
result = 1;
if(ii != 1)
{
for(int i = 1; i < ii; i++)
{
if(an1 % i == 0 && an2 % i == 0)
{
result++;
}
}
}
}
cout << result <<endl;
return 0;
}