Common Divisors 【CodeForces - 182D】【KMP~讀錯題意WA半天】

我的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;
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章