第一种方法是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; }
第二种方法是最小表示法:分别求两个串的最小表示,再进行比较。
#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; }