题目链接:https://vjudge.net/contest/152210#problem/H
题意:给你两个钟,每个钟都有n个指针,问你这两个种是否一样,相当于一个钟旋转一些角度,判断两个钟是否重合
解析:一开始没想到怎么做,后面发现是kmp,也就是每个指针相差的角度存在一个数组了,然后匹配两个数组, 不过比较巧妙的是,需要把一个数组弄成两倍的
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <iostream>
#include <vector>
#include <queue>
#include <set>
using namespace std;
const int maxn = 200000+100;
const int mod = 360000;
int a[maxn],b[maxn];
int c[maxn],d[2*maxn];
int nex[maxn];
int n;
void getNex(int a[],int n)
{
memset(nex,-1,sizeof(nex));
int k = -1,i=0;
while(i<n)
{
if(k==-1 || a[i]==a[k])
{
k++;i++;
nex[i] = k;
}
else
k = nex[k];
}
}
int kmp(int a[],int b[],int n)
{
int i=0,j=0;
getNex(b,n);
while(i<2*n && j<n)
{
if(a[i]==b[j])
{
i++;
j++;
}
else if(j==0)
i++;
else
j = nex[j];
}
if(j==n)
return 1;
else
return 0;
}
int main()
{
scanf("%d",&n);
for(int i=0;i<n;i++)
scanf("%d",&a[i]);
for(int i=0;i<n;i++)
scanf("%d",&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];
c[n-1] = a[0]-a[n-1]+mod;
for(int i=0;i<n-1;i++)
d[i] = b[i+1]- b[i];
d[n-1] = b[0]-b[n-1]+mod;
for(int i=n;i<2*n;i++)
d[i] = d[i-n];
if(kmp(d,c,n))
puts("possible");
else
puts("impossible");
return 0;
}