Input
Output
Sample Input
6 1 2 3 4 5 6 7 6 5 4 3 1
Sample Output
impossible
给你两个钟,每一个钟上有n个指针,现在告诉你这些指针的角度,问你两个钟表的指针是否有
可能重合。
把角度排序,然后相邻的指针求差,但最后的指针与第一个指针的角度差是mod-(a[n-1]-a[0]);
其中mod==360000 但不是很明白为什么要将表面分成360000份
#include<bits/stdc++.h>
using namespace std;
int a[200000<<1],b[200000],c[200000<<1],d[200000],n,m;
const int mod = 360000;
int getNext(int *s,int *next)
{
next[0]=-1;
int k=-1;
int j=0;
while(j<m-1)
{
if(k==-1||s[j]==s[k])
{
++k;++j;next[j]=k;
}else{
k=next[k];
}
}
}
int kmp(int *t,int *p,int *next)
{
int j=0,i=0;
while(i<n&&j<m)
{
if(j==-1||t[i]==p[j]){
i++;j++;
}else{
j=next[j];
}
}
if(j==m){
return i-m+1;
}
return -1;
}
int main()
{
while(cin>>n)
{
m=n;
for(int i=0;i<n;i++)
scanf("%d",a+i);
for(int j=0;j<n;j++)
scanf("%d",b+j);
sort(a,a+n);
sort(b,b+n);
for(int i=0;i<n-1;i++){
c[i]=(a[i+1]-a[i]);
d[i]=(b[i+1]-b[i]);
}
c[n-1]=mod-(a[n-1]-a[0]);
d[n-1]=mod-(b[n-1]-b[0]);
for(int i=n;i<2*n;i++){
c[i]=c[i-n];
}
int next[200000]={0};
getNext(d,next);
n*=2;
int ans=kmp(c,d,next);
if(ans==-1)printf("impossible\n");
else printf("possible\n");
}
}