Problem:
Problem D: Rotation Estimation

Mr. Nod is an astrologist and has defined a new constellation. He took two photos of the
constellation to foretell a future of his friend. The constellation consists of n stars. The shape
of the constellation in these photos are the same, but the angle of them are different because
these photos were taken on a different day. He foretells a future by the difference of the angle
of them.

Your job is to write a program to calculate the difference of the angle of two constellation.

Input

The input is a sequence of datasets. Each dataset is given in the following format:

n
x1,1 y1,1
...
x1,n y1,n
x2,1 y2,1
...
x2,n y2,n

The first line of each dataset contains a positive integers n (n ≤ 1,000). The next n lines contain
two real numbers x1,i and y1,i (|x1,i|, |y1,i| ≤ 100), where (x1,i , y1,i) denotes the coordinates of
the i-th star of the constellation in the first photo. The next n lines contain two real numbers
x2,i and y2,i (|x2,i|, |y2,i| ≤ 100), where (x2,i , y2,i ) denotes the coordinates of the i-th star of the
constellation in the second photo.

Note that the ordering of the stars does not matter for the sameness. It is guaranteed that
distance between every pair of stars in each photo is larger than 10-5.

The input is terminated in case of n = 0. This is not part of any datasets and thus should not
be processed.

Output

For each dataset, you should print a non-negative real number which is the difference of the
angle of the constellation in the first photo and in the second photo. The difference should be in radian, and should not be negative. If there are two or more solutions, you should print
the smallest one. The difference may be printed with any number of digits after decimal point,
provided the absolute error does not exceed 10-7. No extra space or character is allowed.

Sample Input

3
0.0 0.0
1.0 1.0
0.0 1.0
3.0 3.0
2.0 2.0
3.0 2.0
0

Output for the Sample Input

3.14159265359

Solution in C++ (judge verdict: Wrong Answer)

#include<iostream>
#include<vector>
#include<algorithm>
#include<complex>
#include<cmath>
using namespace std;
#define REP(i,b,n) for(int i=b;i<n;i++)
#define rep(i,n)   REP(i,0,n)
#define mp         make_pair
#define pb         push_back
#define fir        first
#define sec        second
#define double long double

typedef complex<double> P;
const double eps = 1e-10;
const double eps2= 1e-8;
const double eps3= 1e-7;
const double pi  = acos(-1);
#define EQ(a,b)    (abs(a-b) < eps)

namespace std{
  bool operator<(const P &a,const P &b){
    if (a.real() != b.real())return a.real() < b.real();
    else return a.imag() < b.imag();
  }
}

double cross(P a,P b){
  return a.real()*b.imag()-a.imag()*b.real();
}

bool is_intersected_ll(P a1,P a2,P b1,P b2){
  return !EQ( cross(a1-a2,b1-b2),0.0);
}

P intersection_ll(P a1,P a2,P b1,P b2){
  P a= a2-a1,b=b2-b1;
  return a1+ a*cross(b,b1-a1)/cross(b,a);
}

bool isp(P a,P b,P c){
  return abs(a-c)+abs(b-c) < abs(a-b) + eps;
}

bool is_intersected_ls(P a1,P a2,P b1,P b2){
  if ( isp(a1,a2,b1))return true;
  if ( isp(a1,a2,b2))return true;
  if ( isp(b1,b2,a1))return true;
  if ( isp(b1,b2,a2))return true;
  if (  ( cross(a2-a1,b1-a1) * cross(a2-a1,b2-a1)<-eps ) && //-EPS
	( cross(b2-b1,a1-b1)*cross(b2-b1,a2-b1)  <-eps))return true;
  else return false;
}

P intersection_ls(P a1,P a2,P b1,P b2){
  P b = b2-b1;
  double d1=fabs(cross(b,a1-b1));//
  double d2=fabs(cross(b,a2-b1));
  double t = d1/(d1+d2);//p[^ t:1-t = d1:d2
  return a1+(a2-a1)*t;
}

double dif(P b,P a){
  double a1=arg(a),b1=arg(b);
  if (a1 < 0)a1+=2*pi;
  double ret = b1-a1;
  while(ret < 0)ret+=2*pi;
  while(ret > 2*pi)ret-=2*pi;
  return ret;
}

P norm(P a,P ori){
  P tmp=a-ori;
  swap(tmp.real(),tmp.imag());
  tmp.real()*=-1;
  return tmp+ori;
}

P rot(P ori,P a,double c,double s,double ang){
  P tmp=a-ori;
  //  P ret=P(tmp.real()*c-tmp.imag()*s,
  //	  tmp.real()*s+tmp.imag()*c);
  //P tmp2=polar(abs(tmp),arg(tmp));
  P ret = polar(abs(tmp),ang+arg(tmp));
  return ori+ret;
}

double solve(int n,P *in,P *in2,P *out,bool &haveans){
  sort(in,in+n);
  sort(in2,in2+n);
  bool check=true;
  static bool used[1000];
  
  rep(i,n){
    if (!(abs(in2[i]-in[i])<eps3))check=false;
  }
  if (check)return 0;


  vector<pair<double,P> > a;
  rep(i,n){
    if (abs(in[i]-in2[0]) < eps)continue;
    P mida=(in[i]+in2[0])/(double)2.0;
    P ta=norm(in[i],mida);
    rep(j,n){
      if (i == j)continue;
      if (abs(in[j]-in2[1]) < eps)continue;
      P midb=(in[j]+in2[1])/(double)2.0;
      P tb=norm(in[j],midb);

//       cout << in[i] <<" " << in2[0] <<" " << in[j]<<" " << in2[1] << endl;
//       cout << mida <<" " <<ta <<" " <<  midb << " " << tb << endl;
//       cout << is_intersected_ll(mida,ta,midb,tb) << endl;
//       cout << endl;

      P candi;
      if (is_intersected_ll(mida,ta,midb,tb)){
	candi=intersection_ll(mida,ta,midb,tb);
      }else if(is_intersected_ls(mida,ta,midb,tb)){
	candi=intersection_ls(mida,ta,midb,tb);
      }else continue;
      
      double da=dif(in[i]-candi,in2[0]-candi),db=dif(in[j]-candi,in2[1]-candi);

      //      if (fabs(da-db)<eps2)
      //	printf("cand (%.10Lf,%.10Lf) %.10Lf %.10Lf %.10Lf\n",
      //	       candi.real(),candi.imag(),da,db,
      //	       fabs(da-db));
      //cout << "cand " << candi << " " << da <<" " << db <<" " << fabs(da-db) << endl;

      if (fabs(da-db)<eps2){
	//cout << "cand " << candi << " " << da <<" " << db <<" " << fabs(da-db) << endl;
	a.pb(mp(da,candi));
      }
    }
  }
  
  sort(a.begin(),a.end());
  double ret = 1e100;
  rep(i,a.size()){
    double cost=cos(a[i].fir),sint=sin(a[i].fir);
    rep(j,n){
      out[j]=rot(a[i].sec,in2[j],cost,sint,a[i].fir);
    }
    sort(out,out+n);
    //cout <<"rot " << a[i].sec <<" " << a[i].fir << endl;
    //rep(j,n)cout<<in[j]<<" " << out[j] << " " << abs(in[j]-out[j]) << endl;
    bool isok=true;

    rep(j,n){
      used[j]=false;
    }
    
    rep(j,n){
      bool hoge=false;
      rep(k,n){
	if (!used[k] && abs(in[j]-out[k]) < eps3){
	  used[k]=true;
	  hoge=true;
	  break;
	}
      }
      if (!hoge){isok=false;break;}
    }

//     rep(j,n){
//       if (abs(in[j]-out[j])<eps3);
//       else {isok=false;break;}
//     }
    if (isok){
      //      rep(j,n)cout<<in[j]<<" " << out[j] << " " << abs(in[j]-out[j]) << endl;
      haveans=true;
      ret=min(ret,a[i].fir);
      if (a[i].fir >pi)ret=min(ret,2*pi-a[i].fir);
      //return a[i].fir;
    }
  }
  if (haveans)return ret;
  return 0;
}

main(){
  int n;
  P in[1000],in2[1000],out[1000];
  while(cin>>n && n){
    rep(i,n){double x,y;cin>>x>>y;in[i]=P(x,y);}
    rep(i,n){double x,y;cin>>x>>y;in2[i]=P(x,y);}
    //printf("%.11Lf\n",min(solve(n,in,in2,out),solve(n,in2,in,out)));
    //printf("%.11Lf\n",min(solve(n,in,in2,out),solve(n,in2,in,out)));
    bool a1=false,a2=false;
    double ans1=solve(n,in,in2,out,a1);
    double ans2=solve(n,in2,in,out,a2);

    if (ans1 > pi)ans1=2*pi-ans1;
    if (ans2 > pi)ans2=2*pi-ans2;    
    //cout << ans1 <<" " << a1 <<" " <<ans2 << " " << a2 << endl;
    
    if (a1 && a2){
      printf("%.11Lf\n",min(ans1,ans2));
    }else if(a1){
      printf("%.11Lf\n",ans1);
    }else if (a2){
      printf("%.11Lf\n",ans2);
    }else {
      printf("%.11Lf\n",(double)0.0);
    }

    //printf("%.11Lf\n",ans1);
  }
  return 0;
}