我的KMP學習日記
題目鏈接
題意:
看題意我以爲它是要我求的是兩個字符串的最小週期的gcd(),後來WA了4發發現好像哪裏不大對,畢竟給的樣例也太特殊的,然後反覆讀題,終於讀懂它終於要幹嘛的了。。。。
題目讓我們求的是有幾個這樣的子字符串,可以恰好的構成原來的這一對字符串,例如“abcabc”與“abcabcabcabcabcabc”可以由"abc"組成也可以由"abcabc"組成,所以答案是個數2。嗚嗚嗚......
思路:
那麼,還是好做的,我們看到兩組字符串,現求出各自的最小週期,這裏呢可以使用KMP()的next[]來做,求最小週期,然後比較兩個最小週期是否相等,不相等直接輸出"0"就是了,然後在看最小週期的倍數,是否能被原字符串的長度整除,能的話就答案+1。
#include <iostream>
#include <cstdio>
#include <cmath>
#include <string>
#include <cstring>
#include <algorithm>
#include <limits>
#include <vector>
#include <stack>
#include <queue>
#include <set>
#include <map>
#define lowbit(x) ( x&(-x) )
#define pi 3.141592653589793
#define e 2.718281828459045
using namespace std;
typedef unsigned long long ull;
typedef long long ll;
const int maxN=1e5+5;
char a[maxN], b[maxN];
int lena, lenb, nex[maxN], las[maxN];
void cal_next_a()
{
nex[0] = nex[1] =0;
int k = 0;
for(int i=2; i<=lena; i++)
{
while(k>0 && a[k+1]!=a[i]) k=nex[k];
if(a[k+1] == a[i]) k++;
nex[i]=k;
}
}
void cal_nex_b()
{
las[0] = las[1] = 0;
int k = 0;
for(int i=2; i<=lenb; i++)
{
while(k>0 && b[k+1]!=b[i]) k=las[k];
if(b[k+1] == b[i]) k++;
las[i]=k;
}
}
bool check(int len)
{
for(int i=1; i<=len; i++)
{
if(a[i]!=b[i]) return false;
}
return true;
}
int gcd(int a, int b) { return b==0?a:gcd(b, a%b); }
int main()
{
while(scanf("%s%s", a+1, b+1)!=EOF)
{
getchar();
lena = (int)strlen(a+1); lenb=(int)strlen(b+1);
cal_next_a();
int tmp_a=lena-nex[lena];
int cycle_a=lena;
if(lena%tmp_a==0)
{
cycle_a=tmp_a;
tmp_a=lena/tmp_a;
}
else tmp_a=1;
cal_nex_b();
int tmp_b=lenb-las[lenb];
int cycle_b=lenb;
if(lenb%tmp_b==0)
{
cycle_b=tmp_b;
tmp_b=lenb/tmp_b;
}
else tmp_b=1;
if(cycle_a == cycle_b)
{
if(check(cycle_a))
{
int ans=0;
for(int i=cycle_a; i<=lena && i<=lenb; i+=cycle_a)
{
if(lena%i==0 && lenb%i==0) ans++;
}
printf("%d\n", ans);
}
else printf("0\n");
}
else printf("0\n");
}
return 0;
}