You have two pictures of an unusual kind of clock. The clock has n hands, each having the same length and no kind of marking whatsoever. Also, the numbers on the clock are so faded that you can’t even tell anymore what direction is up in the picture. So the only thing that you see on the pictures, are n shades of the n hands, and nothing else
You’d like to know if both images might have been taken at exactly the same time of the day, possibly with the camera rotated at different angles.
Task
Given the description of the two images, determine whether it is possible that these two pictures could be showing the same clock displaying the same time.
Input
The first line contains a single integer n (2 ≤ n ≤ 200 000), the number of hands on the clock
Each of the next two lines contains n integers ai (0 ≤ ai < 360 000), representing the angles of the hands of the clock on one of the images, in thousandths of a degree. The first line represents the position of the hands on the first image, whereas the second line corresponds to the second image. The number ai denotes the angle between the recorded position of some hand and the upward direction in the image, measured clockwise. Angles of the same clock are distinct and are not given in any specific order.
Output
Output one line containing one word: possible if the clocks could be showing the same time, impossible otherwise.
题意:给了两个指针数相同的时钟,每个指针都有一个角度(一个圆分成360000份),问这两个钟表可不可能指向的是同一个时间。
思路:其实刚开始做的时候想到哈希,然后被一个取余以及卡常卡到了,后来听大佬说可以用KMP。
KMP做法,因为我们现在有角度,所以我们先对角度进行排序,这样相邻的指针总是在一起的(除首末外),那么此时我们就可以对这些角度作差(a1[], b1[]),这样相邻指针之间的角度差就知道了,如果两个时钟的角度差都一样,那么就可以认定这两个时钟拥有同一个时间。我们再看,由于钟表是圆形的,那么角度差也应该是一个环形,所以要对其中一个角度差求两次了(我用的是a1),注意,首尾相减时,可能为负数,要进行特殊处理。
上面都处理好的话,把b1在a1中跑一遍KMP即可。
代码如下:
#include<cstdio>
#include<cmath>
#include<cstring>
#include<algorithm>
#include<queue>
#include<stack>
#include<string>
#include<map>
#include<set>
#include<vector>
#include<iostream>
#define inf 0x3f3f3f3f
#define ll long long
#define mod 1e9+7
#define N 200010
using namespace std;
const double pi=acos(-1.0);
int a[N],b[N],a1[N<<1],b1[N],Next[N];
void get_next(int *s,int l)
{
int i=0,k=-1;
Next[0]=-1;
while(i<l)
{
if(k<0||s[i]==s[k])
Next[++i]=++k;
else k=Next[k];
}
}
int main()
{
int n;
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);
int m=0;
for(int i=1; i<n; i++)
a1[m++]=a[i]-a[i-1];
a1[m++]=(a[0]-a[n-1]+360000)%360000;
for(int i=1; i<n; i++)
a1[m++]=a[i]-a[i-1];
for(int i=1; i<n; i++)
b1[i-1]=b[i]-b[i-1];
get_next(b1,n-1);
int i=0,k=-1,flag=0;
while(i<m)
{
if(k<0||a1[i]==b1[k])
i++,k++;
else k=Next[k];
if(k>=n-1)
{
flag=1;
break;
}
}
if(flag)printf("possible\n");
else printf("impossible\n");
return 0;
}