The Supersonic Rocket
求由n个点和m个点构成的两个凸包能不能重叠
如果两个凸包边长度和角大小相同,则能重合,所以先建凸包,然后按顺序保存点乘大小(!!不能用叉积[sin],180度内各个角点乘大小[cos]不相等)和边长度,然后对比两序列
#include<stdio.h>
#include<vector>
#include<algorithm>
#include<string.h>
#include<iostream>
#include<fstream>
#include<math.h>
#include<stack>
#include<bitset>
#include<utility>
using namespace std;
typedef long long ll;
const double eps=0.0000000000001;
const int mod=1000000007;
int n,m;
vector<double> cra;
vector<double> crb;
struct P{
ll x;
ll y;
P(){}
P(ll _x,ll _y){
x = _x;y = _y;
}
P operator -(const P &b)const{
return P(x - b.x,y - b.y);
}
};
P ps[100005];
int nt[1000005];
bool cmp_p(P a,P b){
if(a.x==b.x)return a.y<b.y;
else return a.x<b.x;
}
double dot(P b,P a,P c){
return (b.x-a.x)*(c.x-a.x)+(b.y-a.y)*(c.y-a.y);
}
double cross(P b,P a,P c){
return (b.x-a.x)*(c.y-a.y)-(b.y-a.y)*(c.x-a.x);
}
double dist(P a,P b){
return (b.x-a.x)*(b.x-a.x)+(b.y-a.y)*(b.y-a.y);
}
void gch(P*p,int nl,vector<double> &cr){
sort(p,p+nl,cmp_p);
vector<P> ch(nl*2);
int k=0;
for(int i=0;i<nl;i++){
while(k>1&&cross(ch[k-2],ch[k-1],p[i])<=0)k--;
ch[k]=p[i];
k++;
}
for(int i=nl-2,t=k;i>=0;i--){
while(k>t&&cross(ch[k-2],ch[k-1],ps[i])<=0)k--;
ch[k]=p[i];
k++;
}
ch.resize(k-1);
k--;
for(int i=1;i<k-1;i++){
cr.push_back(dist(ch[i-1],ch[i]));
cr.push_back(dot(ch[i-1],ch[i],ch[i+1]));
}
cr.push_back(dist(ch[k-2],ch[k-1]));
cr.push_back(dot(ch[k-2],ch[k-1],ch[0]));
cr.push_back(dist(ch[k-1],ch[0]));
cr.push_back(dot(ch[k-1],ch[0],ch[1]));
/*
for(int i=0;i<cr.size();i++){
cout<<cr[i]<<" ";
}
cout<<endl;
*/
}
void gnt(vector<double> &b){
int bl=b.size();
int k=-1;
int i=0;
nt[0]=-1;
while(i<bl){
if(k==-1||b[k]==b[i]){
i++;k++;
nt[i]=k;
}
else{
k=nt[k];
}
}
}
bool KMP(vector<double> &a,vector<double> &b){
int al=a.size();
int bl=b.size();
//cout<<al<<" "<<bl;
if(al!=bl)return false;
int i=0;
int j=0;
int flag=0;
while(j<bl){
if(i==al){
i=0;
}
if(i==0&&j==0){
flag++;
}
if(flag==2)break;
if(j==-1||a[i]==b[j]){
i++;
j++;
}
else{
j=nt[j];
}
}
if(j==bl)return true;
else return false;
}
int main(){
scanf("%d%d",&n,&m);
ll a,b;
for(int i=0;i<n;i++){
scanf("%I64d%I64d",&a,&b);
ps[i].x=a;
ps[i].y=b;
}
gch(ps,n,cra);
for(int i=0;i<m;i++){
scanf("%I64d%I64d",&a,&b);
ps[i].x=a;
ps[i].y=b;
}
gch(ps,m,crb);
gnt(crb);
if(KMP(cra,crb)){
printf("YES\n");
}
else{
printf("NO\n");
}
return 0;
}
忘记KMP时要循环比较,RTE了很久,坑的是样例输出正确,dev也不报错,愣是没看出来
( _ _)ノ|