分析:
。。。第一次见CF服务器炸了,还好最后unrated了,不然这次死惨。。。
很容易想到,这两个多边形的凸包能通过旋转、平移最终重合,就必然满足条件。
所以就是判断两多边形是否全等。
额。。题解就是标题:顺时针地把两个凸包每个边的长度、每个点的旋转角储存下来(长度不开根号,旋转角用差积表示,这样都是整数)。
如果这两个序列能完全匹配,则说明能够重合。方法就是把其中一个串复制一遍粘在后面,然后在另一个序列上建KMP,然后依次匹配,看能否匹配到末尾。
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<stack>
#include<map>
#include<cmath>
#define SF scanf
#define PF printf
#define MAXN 400010
#define EPS 1e-7
using namespace std;
typedef long long ll;
const double Pi=acos(-1);
struct node{
ll x,y;
node(){}
node(ll xx,ll yy):x(xx),y(yy) {}
node operator + (const node &a) const {
return node(x+a.x,y+a.y);
}
node operator - (const node &a) const {
return node(x-a.x,y-a.y);
}
node operator * (const double &t) const {
return node(x*t,y*t);
}
double operator *(const node &a) const{
return x*a.x+y*a.y;
}
double operator ^(const node &a) const{
return x*a.y-y*a.x;
}
bool operator <(const node &a) const {
return a.x!=x?x<a.x:y<a.y;
}
};
bool cmp(node a,node b){
return b<a;
}
class Curex{
public:
node p[MAXN],l1[MAXN];
stack<node> s1,s;
ll ans[MAXN];
int n,cnt1,cnt2;
void solve(node a1[],int &cnt){
s.push(p[1]);
s1.push(p[1]);
s1.push(p[2]);
for(int i=3;i<=n;i++){
while(!s.empty()&&((p[i]-s.top())^(s1.top()-s.top()))<=0){
s.pop();
s1.pop();
}
s.push(s1.top());
s1.push(p[i]);
}
while(!s1.empty()){
a1[++cnt]=s1.top();
s1.pop();
}
while(!s.empty())
s.pop();
}
void init(int n1){
n=n1;
for(int i=1;i<=n;i++)
SF("%I64d%I64d",&p[i].x,&p[i].y);
sort(p+1,p+1+n);
solve(l1,cnt1);
sort(p+1,p+1+n,cmp);
cnt1--;
solve(l1,cnt1);
cnt1--;
cnt2=0;
for(int i=1;i<=cnt1;i++){
int las,nxt;
if(i==1)
las=cnt1;
else
las=i-1;
if(i==cnt1)
nxt=1;
else
nxt=i+1;
ans[++cnt2]=(ll)((l1[nxt]-l1[i])*(l1[las]-l1[i]));
ll xx=(l1[nxt]-l1[i]).x;
ll yy=(l1[nxt]-l1[i]).y;
ans[++cnt2]=xx*xx+yy*yy;
}
}
}fir,sec;
int las[MAXN];
void build(ll a[]){
int len=fir.cnt2;
for(int i=0;i<len;i++){
int x=i;
while(x){
x=las[x];
if(a[x+1]==a[i+1]){
las[i+1]=x+1;
break;
}
}
}
}
bool check(int n,ll a[],int m,ll b[]){
int lasx=0;
for(int i=1;i<=m;i++){
while(lasx&&a[lasx+1]!=b[i])
lasx=las[lasx];
if(a[lasx+1]==b[i])
lasx++;
if(lasx==n)
return 1;
}
return 0;
}
int main(){
int n,m;
SF("%d%d",&n,&m);
fir.init(n);
sec.init(m);
if(fir.cnt1!=sec.cnt1){
PF("NO");
return 0;
}
build(fir.ans);
for(int i=1;i<=sec.cnt2;i++)
sec.ans[sec.cnt2+i]=sec.ans[i];
sec.cnt2*=2;
if(check(fir.cnt2,fir.ans,sec.cnt2,sec.ans))
PF("YES\n");
else
PF("NO\n");
}