题目链接:点击链接
题意:输入n,有n个指针,下面两行,第一行有n个数,代表表一的n个指针的指向,第一行有n个数,代表 表二的指针指向,看看经旋转,两个图形能不能重合。
思路:排序,相邻数做差,最后一个数是,a[0] - a[n-1] + 360000,因为a[0] - a[n-1] 一定为负数。把a数组的差值倍增,然后看看b数组的差值序列是不是在a数组的差值序列中存在,做kmp。
代码:
#include<bits/stdc++.h>
using namespace std;
#define Max 200020
int a[Max*2],b[Max];
int f[Max];
int n;
void getF() // 求b数组的f[],也就是差不多b数组与b数组匹配了
{
int i,j; // 想着写
f[0] = -1; // 先定义f[0]等于-1
for(int i = 1;i<n;i++){
j = f[i-1];
while(b[j+1]!=b[i]&&j!=-1) // 运用前面的所知道匹配个数
j = f[j];
if(b[j+1]==b[i])
f[i] = j + 1; //最长前缀后缀
else f[i] = -1;
}
}
int sovle()
{
int j = -1;
int kk = 0;
for(int i = 0;i<2*n;i++){
while(b[j+1]!=a[i]&&j!=-1)
j = f[j];
if(b[j+1]==a[i]){
j++;
if(j==n-1)
return 1;
}
}
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);
int a0 = a[0],b0 = b[0];
for(int i = 1;i<n;i++){
a[i-1] = a[i] - a[i-1];
b[i-1] = b[i] - b[i-1];
}
a[n-1] = a0 - a[n-1] + 360000;
b[n-1] = b0 - b[n-1] + 360000;
for(int i = 0;i<n;i++) //倍增a数组;
a[i+n] = a[i];
getF(); // 获取F数组
if(sovle()) printf("possible\n");
else printf("impossible\n");
return 0;
}