囤了一个星期。。今天看了下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 ",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 ",a[0].abs()); 57 // printf("%.11f ",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 ",ans); 71 } 72 /** 73 先求出来每个点对中心的偏移量。 74 确实是乱序的,但是我们可以极角排序,这样一定是一个 75 循环移位匹配到另一个循环移位。 76 所以枚举n次就可以,check也十分简单 77 */