求两个字符串(数字串也是一样)是不是循环同构

第一种方法是kmp:将一个数组复制一次,然后再用另一个进行匹配。

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>

using namespace std;

const int N = 200005;
const int MOD = 360000;

int a[N],b[N],c[2*N],d[N],f[N];

void getFail(int n){
    f[0]=0;f[1]=0;
    for(int i=1;i<n;i++){
        int j=f[i];
        while(j&&d[i]!=d[j]) j=f[j];
        f[i+1] = d[i]==d[j]?j+1:0;
    }
}

bool kmp(int n)
{
    getFail(n);
    int j =0;
    for(int i=0;i<2*n;i++){
        while(j&&d[j]!=c[i]) j=f[j];
        if(d[j]==c[i]) j++;
        if(j==n) return true;
    }
    return false;
}

void run()
{
    int n;
    while(cin>>n)
    {
        for(int i=0;i<n;i++) cin>>a[i];
        for(int i=0;i<n;i++) cin>>b[i];
        sort(a,a+n);sort(b,b+n);

        for(int i=0;i<n-1;i++)
        {
            c[i]=(a[i+1]-a[i]+MOD)%MOD;
            c[n+i]=c[i];
            d[i]=(b[i+1]-b[i]+MOD)%MOD;
        }
        c[n-1]=(MOD-a[n-1]+a[0])%MOD;
        c[2*n-1]=c[n-1];
        d[n-1]=(MOD-b[n-1]+b[0])%MOD;

        //for(int i=0;i<2*n;i++) cout<<c[i]<<" ";cout<<endl;
        //for(int i=0;i<n;i++) cout<<d[i]<<" ";cout<<endl;

        if(kmp(n)) puts("possible");
        else puts("impossible");

    }
}

int main()
{
    ios::sync_with_stdio(0);
    run();
    //cout << "Hello world!" << endl;
    return 0;
}
View Code

第二种方法是最小表示法:分别求两个串的最小表示,再进行比较。

#include <iostream>
#include <algorithm>
#include <cstdio>

using namespace std;

const int N = 200005;
const int MOD = 360000;

int a[N],b[N],c[N],d[N];

int getminsub(int* a,int len)
{
    int i=0,j=1,k=0;
    while(i<len&&j<len&&k<len)
    {
        if(k==len) break;
        if(i==j) j++;
        int ni=i+k,nj=j+k;
        if(ni>=len) ni-=len;
        if(nj>=len) nj-=len;
        if(a[ni]>a[nj])
        {
            i+=(k+1);
            k=0;
        }
        else if(a[ni]<a[nj])
        {
            j+=(k+1);
            k=0;
        }
        else k++;
    }
    return i;
}

void run()
{
    int n;
    while(cin>>n)
    {
        for(int i=0;i<n;i++) cin>>a[i];
        for(int i=0;i<n;i++) cin>>b[i];
        sort(a,a+n);sort(b,b+n);
        for(int i=0;i<n-1;i++)
        {
            c[i]=(a[i+1]-a[i]+MOD)%MOD;
            d[i]=(b[i+1]-b[i]+MOD)%MOD;
        }
        c[n-1]=(MOD-a[n-1]+a[0])%MOD;
        d[n-1]=(MOD-b[n-1]+b[0])%MOD;

        //for(int i=0;i<n;i++) cout<<c[i]<<" ";cout<<endl;
        //for(int i=0;i<n;i++) cout<<d[i]<<" ";cout<<endl;

        int f=getminsub(c,n);
        int k=getminsub(d,n);

        //cout<<f<<" "<<k<<endl;

        int l=0;bool cp=true;
        while(l<n)
        {
            if(c[f]==d[k])
            {
                l++;
                f++;if(f==n) f=0;
                k++;if(k==n) k=0;
            }
            else {cp=false;break;}
        }

        if(cp) puts("possible");
        else puts("impossible");

    }
}

int main()
{
    run();
    //cout << "Hello world!" << endl;
    return 0;
}
View Code
原文地址:https://www.cnblogs.com/BugClearlove/p/4442860.html