100837D

囤了一个星期。。今天看了下vj上 sysuteam7 三年半之前的代码。。

深刻地认识到了自己智商不足的问题。

先求出来每个点对中心的偏移量。
确实是乱序的,但是我们可以极角排序,这样一定是一个
循环移位匹配到另一个循环移位。
所以枚举n次就可以,check也十分简单
 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 typedef double db;
 4 const db eps = 1e-6;
 5 const db pi = acos(-1);
 6 int sign(db k){
 7     if(k>eps)return 1;else if(k<-eps)return -1;return 0;
 8 }
 9 int cmp(db k1,db k2){ return sign(k1-k2);}
10 struct point{
11     db x,y;
12     point operator+(const point &k1)const { return point{x+k1.x,y+k1.y};}
13     point operator-(const point &k1)const { return point{x-k1.x,y-k1.y};}
14     point operator *(db k1)const{ return point{x*k1,y*k1};}
15     point operator/(db k1)const { return point{x/k1,y/k1};}
16     int operator == (const point &k1) const{return cmp(x,k1.x)==0&&cmp(y,k1.y)==0;}
17     bool operator<(const point k1)const {
18         int a = cmp(x,k1.x);
19         if(a==-1)return 1;else if(a==1) return 0;
20         else return cmp(y,k1.y)==-1;
21     }
22     db abs(){ return sqrt(x*x+y*y);}
23     db abs2(){return x*x+y*y;}
24     db dis(point k1){ return ((*this)-k1).abs();}
25     point unit(){db w = abs(); return point{x/w,y/w};}
26     point turn90(){return point{-y,x};}
27     db getP()const{return sign(y)==-1||(sign(y)==0&&sign(x)==-1);}
28 };
29 db cross(point k1,point k2){return k1.x*k2.y-k1.y*k2.x;}
30 db dot(point k1,point k2){return k1.x*k2.x+k1.y*k2.y;}
31 int compareangle (point k1,point k2){//[0,2pi]
32     return k1.getP()<k2.getP()||(k1.getP()==k2.getP()&&sign(cross(k1,k2))>0)||(k1.getP()==k2.getP()&&sign(cross(k1,k2))==0&&abs(k1.x)<abs(k2.x));
33 }
34 int n;
35 point a[1005],b[1005];
36 point o1,o2;
37 int main(){
38     //freopen("d.in","r",stdin);
39     //freopen("d.out","w",stdout);
40     scanf("%d",&n);
41     if(n==1) return 0*printf("%.11f\n",0.0);
42     for(int i=0;i<n;i++){
43         scanf("%lf%lf",&a[i].x,&a[i].y);
44         o1=o1+a[i];
45     }
46     for(int i=0;i<n;i++){
47         scanf("%lf%lf",&b[i].x,&b[i].y);
48         o2=o2+b[i];
49     }
50     o1=o1/n,o2=o2/n;
51     for(int i=0;i<n;i++){
52         a[i]=a[i]-o1,b[i]=b[i]-o2;
53     }
54     sort(a,a+n,compareangle);
55     sort(b,b+n,compareangle);
56 //    printf("%.11f\n",a[0].abs());
57 //    printf("%.11f\n",b[2].abs());
58     db ans = pi;
59     for(int i=0;i<n;i++){//[0,n)~[i,i+n)
60         bool f=1;
61         for(int j=0;j<n;j++){
62             if(cmp(a[j].abs(),b[(i+j)%n].abs())!=0){
63                 f=0;break;
64             }
65         }
66         if(f){
67             ans=min(ans,acos(dot(a[0],b[i])/a[0].abs()/b[i].abs()));
68         }
69     }
70     printf("%.11f\n",ans);
71 }
72 /**
73  先求出来每个点对中心的偏移量。
74  确实是乱序的,但是我们可以极角排序,这样一定是一个
75  循环移位匹配到另一个循环移位。
76  所以枚举n次就可以,check也十分简单
77  */
View Code

 

 

 

posted @ 2019-04-01 21:06  MXang  阅读(132)  评论(0编辑  收藏  举报