ACM Live Archive 4161 – Spherical Mirrors

Category : Geometry
Solution:
First we need to find the intersection between a sphere and a line.
a line is denoted by an origin and a direction vector.
a sphere is denoted a centre and radius. To find the intersection ,lets consider the equation of sphere.

Let p be a point on the sphere. Then the following equation holds
|p-c|^2 = r^2          ........... (1)
where c is the centre of the sphere and r is radius.

Now if the line intersects the sphere in point p, then we can write p as
p = o + d * x;
where o is origin of the line and d is direction unit vector of the line. x is the scaling factor.
putting p in equation (1)
|o+dx-c|^2 =r^2 \\  (dx).(dx) + 2*(dx).(o-c) + (o-c).(o-c) - r *r = 0
This is a quadratic equation of x in form ax^2 + bx + c = 0
where
a = d*d \\  b = 2 * (d.(o-c))\\  c = (o-c).(o-c) - r*r\\    discriminant = b * b - 4 * a * c;
if discriminant >= 0 , then the line intersects the sphere.
We can find x.
We will only take the value of x which is greater than ZERO (why ? )

After finding x , We can find the intersecting point.

Now we need to rotate the direction vector. This is shown in the following ways Reflection

/*
 *************************
 Id  : Matrix.code
 Task:
 Date: 2016-02-04

 **************************
 */


#include<cstdio>
#include<iostream>
#include<cmath>
#include<algorithm>
#include<vector>

using namespace std;


/*------- Constants---- */

#define Long                    long long
#define ull                     unsigned long long
#define mod                     1000000007
#define MEMSET_INF              63
#define MEM_VAL                 1061109567
#define forn(i,n)               for( int i=0 ; i < n ; i++ )
#define mp(i,j)                 make_pair(i,j)
#define lop(i,a,b)              for( int i = (a) ; i < (b) ; i++)
#define pb(a)                   push_back((a))
#define SZ(a)                   (int) a.size()
#define all(x)                  (x).begin(),(x).end()
#define gc                      getchar_unlocked
#define PI                      acos(-1.0)
#define INF                     1<<29
#define EPS                     1e-12
#define Fr                      first
#define Sc                      second
#define Sz                      size()
#define lc                      ((n)<<1)
#define rc                      ((n)<<1|1)
#define db(x)                   cout << #x << " -> " << x << endl;
#define Di(n)                   int n;si(n)
#define Dii(a,b)                int a,b;si(a);si(b)
#define Diii(a,b,c)             int a,b,c;si(a);si(b);si(c)
#define Si(n)                   si(n)
#define Sii(a,b)                si(a);si(b)
#define Siii(a,b,c)             si(a);si(b);si(c)
#define min(a,b)                ((a)>(b) ? (b) : (a) )
#define max(a,b)                ((a)>(b) ? (a):(b))
/*---- short Cuts ------- */
#define ms(ara_name,value) memset(ara_name,value,sizeof(ara_name))
typedef pair<int, int> ii;
typedef vector<int> vi ;
typedef vector<Long> vl;
/*------ template functions ------ */
#ifndef getchar_unlocked
#define getchar_unlocked getchar
#endif
template<class T> inline void si(T &x){register int c = gc();x = 0;int neg = 0;for(;((c<48 | c>57) && c != '-');c = gc());
      if(c=='-') {neg=1;c=gc();}for(;c>47 && c<58;c = gc()) {x = (x<<1) + (x<<3) + c - 48;}if(neg) x=-x;}
Long bigmod(Long p,Long e,Long M){Long ret = 1;for(; e > 0; e >>= 1){if(e & 1) ret = (ret * p) % M;p = (p * p) % M;} return ret;}
Long gcd(Long a,Long b){if(b==0)return a;return gcd(b,a%b);}
Long modinverse(Long a,Long M){return bigmod(a,M-2,M);}
void io(){freopen("/Users/MyMac/Desktop/in.txt","r",stdin);}

/*************************** END OF TEMPLATE ****************************/
#define Z(x)      (abs(x) < EPS)
#define ZN(x)     ( x < 0 || Z(x))
#define ZP(x)     ( x > 0 || Z(x))
const int N = 1005;
typedef double T;

struct PT{
      T x,y,z;
      PT(){}
      PT(T x,T y,T z):x(x),y(y),z(z){}
      void scan(){cin >> x >> y >> z;}
      PT operator + (const PT &p) const{ return PT(x+p.x,y+p.y,z+p.z);}
      PT operator - (const PT &p) const{ return PT(x-p.x,y-p.y,z-p.z);}
      PT operator * (const double c) const {return PT(x*c,y*c,z*c);}
      double abs(){ return sqrt(x*x+y*y+z*z);}
      void normal(){
            double d = this->abs();
            if(fabs(d) < EPS) return;
            x/=d;
            y/=d;
            z/=d;
      }
      void print() { printf("(%f %f %f)",x,y,z);}

};
double dot(PT a,PT b){ return a.x*b.x+a.y*b.y+a.z*b.z;}


struct Sp{
      PT cen;
      double rad;
      Sp(){}
};

vector<Sp> vs;
int main()
{
      //freopen("in.txt","r",stdin);
      int n;
      while(scanf("%d",&n)==1) {
            if(n==0) break;
            PT org(0,0,0);
            PT dir;
            dir.scan();
            dir.normal();
            Sp sp;
            for(int i= 0;i < n ;i ++) {
                  sp.cen.scan();
                  cin >> sp.rad;
                  vs.pb(sp);
            }

            PT ans;
            while(1) {
                  vector<pair<double,int> > Map;
                  for(int i= 0;i < n ;i ++) {
                        double a = dot(dir,dir);
                        double b = 2 * dot(dir, org - vs[i].cen);
                        double c = dot(org-vs[i].cen , org - vs[i].cen) - vs[i].rad * vs[i].rad;
                        double disc = b * b - 4 * a * c;
                        if(ZP(disc) ) {
                              double x1 = -b - sqrt(disc);
                              double x2 = -b + sqrt(disc);
                              x1/=(2*a); x2/=(2*a);
                              vector<double> k;
                              if(x1>EPS) k.pb(x1);
                              if(x2 > EPS) k.pb(x2);
                              sort(all(k));
                              if(k.size()) {
                                    Map.pb(mp(k[0],i));
                              }
                        }
                  }
                  if(Map.size() == 0 ) break;
                  sort(all(Map));
                  double x = Map[0].first;
                  double col = Map[0].second;
                  org = org + dir * x;
                  PT nor = org - vs[col].cen;nor.normal();
                  dir = dir - nor * 2 * dot(dir,nor);
                  ans = org;
                  Map.clear();

            }
            printf("%f %f %f\n",ans.x, ans.y,ans.z);
            vs.clear();
      }
      return 0;
}

Lightoj – 1130 – Intersection between Circle and Rectangle

Category : Geometry
Solution: Will be discussed Soon.

/*
 *************************
 Id  : Matrix.code
 Task: 1130 - Intersection between Circle and Rectangle
 Date: 2016-02-25

 **************************
 */


#include <bits/stdc++.h>
using namespace std;

/*------- Constants---- */

#define Long                    long long
#define ull                     unsigned long long
#define mod                     1000000007
#define MEMSET_INF              63
#define MEM_VAL                 1061109567
#define forn(i,n)               for( int i=0 ; i < n ; i++ )
#define mp(i,j)                 make_pair(i,j)
#define lop(i,a,b)              for( int i = (a) ; i < (b) ; i++)
#define pb(a)                   push_back((a))
#define SZ(a)                   (int) a.size()
#define all(x)                  (x).begin(),(x).end()
#define gc                      getchar_unlocked
#define PI                      acos(-1.0)
#define INF                     1<<29
#define EPS                     1e-9
#define Fr                      first
#define Sc                      second
#define Sz                      size()
#define lc                      ((n)<<1)
#define rc                      ((n)<<1|1)
#define db(x)                   cout << #x << " -> " << x << endl;
#define Di(n)                   int n;si(n)
#define Dii(a,b)                int a,b;si(a);si(b)
#define Diii(a,b,c)             int a,b,c;si(a);si(b);si(c)
#define Si(n)                   si(n)
#define Sii(a,b)                si(a);si(b)
#define Siii(a,b,c)             si(a);si(b);si(c)
#define min(a,b)                ((a)>(b) ? (b) : (a) )
#define max(a,b)                ((a)>(b) ? (a):(b))
/*---- short Cuts ------- */
#define ms(ara_name,value) memset(ara_name,value,sizeof(ara_name))
typedef pair<int, int> ii;
typedef vector<int > vi ;
typedef vector<Long> vl;
/*------ template functions ------ */
#ifndef getchar_unlocked
#define getchar_unlocked getchar
#endif
template<class T> inline void si(T &x){register int c = gc();x = 0;int neg = 0;for(;((c<48 | c>57) && c != '-');c = gc());
      if(c=='-') {neg=1;c=gc();}for(;c>47 && c<58;c = gc()) {x = (x<<1) + (x<<3) + c - 48;}if(neg) x=-x;}
Long bigmod(Long p,Long e,Long M){Long ret = 1;for(; e > 0; e >>= 1){if(e & 1) ret = (ret * p) % M;p = (p * p) % M;} return ret;}
Long gcd(Long a,Long b){if(b==0)return a;return gcd(b,a%b);}
Long modinverse(Long a,Long M){return bigmod(a,M-2,M);}
void io(){freopen("/Users/MyMac/Desktop/in.txt","r",stdin);}

/*************************** END OF TEMPLATE ****************************/

const int N = 1001;

#define EPS		1e-12
#define _abs(x)		(((x)>0)?(x):-(x))
#define _max(x,y)	(((x)>(y))?(x):(y))
#define _min(x,y)	(((x)<(y))?(x):(y))

#define E(x,y)	(_abs((x)-(y)) < EPS)
#define Z(x)	(_abs(x) < EPS)
#define ZN(x)	(x < 0 || Z(x))
#define ZP(x)	(x > 0 || Z(x))
#define S(x)	((x)*(x))

#define UNDEF	-1
#define OUTSIDE	0
#define INSIDE	1
#define CUT     2
//0 <= x1 <= x2 <= R
double ySlice(double R,double x1,double x2){		// area bounded by y=0, x=x1, x=x2, y = sqrt(R*R - x*x)
	double a,t1,t2;

	assert( ZP(x1) );
	assert( ZP(x2-x1) );
	assert( ZP(R-x2) );

	t2 = acos(x2/R);
	t1 = acos(x1/R);
	a  = 0.5*( S(R)*(t1-t2) + R*(x2*sin(t2) - x1*sin(t1)) );

	assert( ZP(a) );

	return a;
}

//rect(x1,x2,y1,y2) must be in the FIRST quadrant, 0<=x1<=x2, 0<=y1<=y2
double posXYRectCommon(double R,double x1,double x2,double y1,double y2,int &flag){
	double x3,x4,a,d11,d12,d21,d22;

	assert( ZP(x1));
	assert( ZP(y1));
	assert( ZP(x2-x1) );
	assert( ZP(y2-y1) );

	d11 = S(x1)+S(y1) - S(R);
	d12 = S(x1)+S(y2) - S(R);
	d21 = S(x2)+S(y1) - S(R);
	d22 = S(x2)+S(y2) - S(R);

	if( ZN(d22) ){					//case 1
		a  = (x2-x1)*(y2-y1);
		flag = _max(flag,INSIDE);
	}
	else if( ZN(d12) && ZN(d21) ){	//case 2
		x3 = sqrt(S(R) - S(y2));	//x3 <= x2
		a  = (x3-x1)*(y2-y1) + ySlice(R,x3,x2) - (x2-x3)*y1;
		flag = _max(flag,CUT);
		assert(ZP(x2-x3));
	}
	else if( ZN(d12) ){				//case 3
		x3 = sqrt(S(R) - S(y2));	//x3 <= x4
		x4 = sqrt(S(R) - S(y1));
		a  = (x3-x1)*(y2-y1) + ySlice(R,x3,x4) - (x4-x3)*y1;
		flag = _max(flag,CUT);
		assert(ZP(x4-x3));
	}
	else if( ZN(d21) ){				//case 4
		a  = ySlice(R,x1,x2) - (x2-x1)*y1;
		flag = _max(flag,CUT);
	}
	else if( ZN(d11) ){				//case 5
		x3 = sqrt(S(R) - S(y1));	//x1 <= x3
		a  = ySlice(R,x1,x3) - (x3-x1)*y1;
		flag = _max(flag,CUT);
		assert(ZP(x3-x1));
	}
	else{							//case 6
		a = 0;
		flag = _max(flag,OUTSIDE);
	}

	assert( ZP(a) );
	assert( ZP( (x2-x1)*(y2-y1) - a) );

	return a;
}

double XYRectCommon(double x,double y,double R,double x1,double x2,double y1,double y2,int &flag){
	double a;
	x1-=x;
	x2-=x;
	y1-=y;
	y2-=y;

	flag = UNDEF;

	if(ZP(x1) && ZP(y1)){
		a = posXYRectCommon(R,x1,x2,y1,y2,flag);
	}
	else if(ZP(x1)){		//y1 < 0
            if(ZN(y2)) a = posXYRectCommon(R,x1,x2,-y2,-y1,flag);
            else {
                  a = posXYRectCommon(R,x1,x2,0, y2,flag);
                  a+= posXYRectCommon(R,x1,x2,0,-y1,flag);
            }

	}
	else if(ZP(y1)){		//x1 < 0
            if(ZN(x2)) {
                  a = posXYRectCommon(R,-x2,-x1,y1,y2,flag);
            }else {
		a = posXYRectCommon(R,0, x2,y1,y2,flag);
		a+= posXYRectCommon(R,0,-x1,y1,y2,flag);
            }
	}
	else{			//x1 < 0 && y1 < 0
            if(ZN(x2) &&ZN(y2)) a = posXYRectCommon(R,-x2,-x1,-y2,-y1,flag);
		else if(ZN(y2)) a = XYRectCommon(0,0,R,x1,x2,-y2,-y1,flag);
		else if(ZN(x2)) a = XYRectCommon(0,0,R,-x2,-x1,y1,y2,flag);
		else {
                  a = posXYRectCommon(R,0, x2,0, y2,flag);
                  a+= posXYRectCommon(R,0, x2,0,-y1,flag);
                  a+= posXYRectCommon(R,0,-x1,0, y2,flag);
                  a+= posXYRectCommon(R,0,-x1,0,-y1,flag);
		}
	}
	return a;
}

int main(){

      //freopen("in.txt","r",stdin);
	int flag;
	double x,y,R,x1,x2,y1,y2;
      Di(t);
      int cs = 0;
      while(t--) {
            scanf("%lf%lf%lf%lf%lf%lf%lf",&x,&y,&R,&x1,&y1,&x2,&y2);
		printf("Case %d: %.10f\n",++cs,XYRectCommon(x,y,R,x1,x2,y1,y2,flag));
      }


	return 0;
}



Geometry Funs

Category : Geometry, Convex Hull
Problem Link : Biathlon 2.0
Short Description :
Given n pair of integer(a,b). Also given m pair of integer (x,y).
For each n pair , output the min( a * xi + b * yi) where 1<=i<=m

Solution:

    First build the convex hull of m pair of interger as point. As the point inside the convex hull can not give minimum value for a given point. Because the same value can be obtained from the point lying in the convex hull.
    Ternary search on the point of the convex hull. Find the minimum

/*
 *************************
 Id  : Matrix.code
 Task: H. Biathlon 2.0
 Date: 2016-02-14

 **************************
 */


#include <bits/stdc++.h>
using namespace std;

#include<ext/pb_ds/assoc_container.hpp>
#include<ext/pb_ds/tree_policy.hpp>
using namespace __gnu_pbds;
template <typename T>
using ordered_set = tree<T, null_type, less<T>, rb_tree_tag, tree_order_statistics_node_update>;


/*------- Constants---- */

#define Long                    long long
#define ull                     unsigned long long
#define mod                     1000000007
#define MEMSET_INF              63
#define MEM_VAL                 1061109567
#define forn(i,n)               for( int i=0 ; i < n ; i++ )
#define mp(i,j)                 make_pair(i,j)
#define lop(i,a,b)              for( int i = (a) ; i < (b) ; i++)
#define pb(a)                   push_back((a))
#define SZ(a)                   (int) a.size()
#define all(x)                  (x).begin(),(x).end()
#define gc                      getchar_unlocked
#define PI                      acos(-1.0)
#define INF                     1e18
#define EPS                     1e-2
#define Fr                      first
#define Sc                      second
#define Sz                      size()
#define lc                      ((n)<<1)
#define rc                      ((n)<<1|1)
#define db(x)                   cout << #x << " -> " << x << endl;
#define Di(n)                   int n;si(n)
#define Dii(a,b)                int a,b;si(a);si(b)
#define Diii(a,b,c)             int a,b,c;si(a);si(b);si(c)
#define Si(n)                   si(n)
#define Sii(a,b)                si(a);si(b)
#define Siii(a,b,c)             si(a);si(b);si(c)
#define min(a,b)                ((a)>(b) ? (b) : (a) )
#define max(a,b)                ((a)>(b) ? (a):(b))
/*---- short Cuts ------- */
#define ms(ara_name,value) memset(ara_name,value,sizeof(ara_name))
typedef pair<int, int> ii;
typedef vector<int > vi ;
typedef vector<Long> vl;
/*------ template functions ------ */
#ifndef getchar_unlocked
#define getchar_unlocked getchar
#endif
template<class T> inline void si(T &x){register int c = gc();x = 0;int neg = 0;for(;((c<48 | c>57) && c != '-');c = gc());
      if(c=='-') {neg=1;c=gc();}for(;c>47 && c<58;c = gc()) {x = (x<<1) + (x<<3) + c - 48;}if(neg) x=-x;}
Long bigmod(Long p,Long e,Long M){Long ret = 1;for(; e > 0; e >>= 1){if(e & 1) ret = (ret * p) % M;p = (p * p) % M;} return ret;}
Long gcd(Long a,Long b){if(b==0)return a;return gcd(b,a%b);}
Long modinverse(Long a,Long M){return bigmod(a,M-2,M);}
void io(){freopen("/Users/MyMac/Desktop/in.txt","r",stdin);}

/*************************** END OF TEMPLATE ****************************/

const int N = 5e5+5;

Long  x[N],y[N],c[N],d[N];

struct PT{
      double x,y;
      PT operator + (const PT &q) {return {x+q.x,y+q.y};}
      PT operator - (const PT &q) {return {x-q.x,y-q.y};}
      PT operator * (double c   ) {return {x*c,y*c};    }
      PT operator / (double c  ) {return {x/c,y/c};}
}P[N];
double sqr(double a){return a*a;}
double dist2(PT a, PT b) {return sqr(a.x-b.x) + sqr(a.y-b.y);}
double dot(PT a,PT b) {return a.x*b.x+a.y*b.y;}
double cross(PT a,PT b){return a.x*b.y-a.y*b.x;}
double DIM(PT a) {return sqrt(a.x*a.x+a.y*a.y);}


PT pivot;
bool cmp(PT a, PT b)
{
      double d = cross(a-pivot,b-pivot);
      if(d>0) return 1;
      else if(d<0)return 0;
      else {
            double d1 = dist2(pivot,a);
            double d2 = dist2(pivot,b);
            return d1<d2;
      }
}
vector<PT> Hul, H;

void CH(vector<PT> &P , int SZ)
{
      double iy = INF ;
      int id = -1;
      for(int i= 0;i < SZ; i ++ ) {
            if(P[i].y < iy){
                  iy = P[i].y, id = i;
            }
      }
      swap(P[0],P[id]);
      pivot = P[0];

      sort(all(P), cmp);
      Hul.pb(P[0]);
      Hul.pb(P[1]);
      for(int i = 2;i < SZ ; i++ ) {
            while(Hul.size() > 1 && cross(Hul[Hul.size() - 1] - Hul[Hul.size() -2 ] , P[i] - Hul[Hul.size()-1] ) < 0 ) Hul.pop_back();
            Hul.pb(P[i]);
      }


}
vector<PT> pp;



int main()
{
      //freopen("in.txt","r",stdin);
      int n;
      scanf("%d",&n);
      for(int i = 0; i < n ;i ++ ) {
            Sii(x[i],y[i]);
      }
      int m;
      Si(m);
      for(int i = 0; i < m ;i ++ ) {
            Sii(c[i],d[i]);
            pp.push_back({c[i], d[i]});
      }
      pp.push_back({INF,INF});

      CH(pp,pp.size());


      for(int i = 0;i < SZ(Hul); i ++ ) {
            if(fabs(Hul[i].x - INF) < EPS) {
                  for(int j= i + 1 ; j < SZ(Hul) ; j ++ ) H.pb(Hul[j]);
                  for(int j= 0; j < i; j ++ ) H.pb(Hul[j]);
                  break;
            }
      }

      for(int i = 0; i < n; i ++ ) {
            int x1 = x[i], y1 = y[i];
            Long low = 0, high = H.size()-1, ans= 4e18;

            while(low <= high ) {
                  Long f = low + (high - low ) /3;
                  Long g = high- (high - low) / 3 ;
                  Long ff = x1*H[f].x + y1 *H[f].y;
                  Long fg = x1*H[g].x + y1 *H[g].y;

                  if(ff < fg) {
                        ans = min(ans, ff);
                        high = g-1;
                  }else {
                        ans = min(ans, fg);
                        low = f+1;
                  }
            }
            printf("%lld ", ans);
      }

      return 0;

}

Geometry Template


#include <bits/stdc++.h>
using namespace std;

double INF = 1e100;
double EPS = 1e-12;


struct PT {
      double  x,y;
      PT(double x=0, double y=0) : x(x), y(y) {}
      PT(const PT &p) : x(p.x), y(p.y)    {}
      PT operator + (const PT &p) const { return PT(x+p.x , y + p.y);}
      PT operator - (const PT &p) const { return PT(x-p.x , y - p.y);}
      PT operator * (double c) const { return PT(x*c,y*c);}
      PT operator / (double c) const { return PT(x/c,y/c);}
      void input(){scanf("%lf %lf",&x,&y);}
};

double dot(PT p,PT q){ return p.x * q.x + p.y * q.y;}
double cross(PT p,PT q) {return p.x*q.y - p.y*q.x;}
double dist2(PT p,PT q) {return dot(p-q , p-q);}
double DIM(PT p) {return sqrt(p.x*p.x+p.y*p.y);}

// rotate a point CCW or CW around the origin
PT RotCCW90(PT p){return PT(-p.y,p.x);}
PT RotCW90(PT p)   {return PT(p.y,-p.x);}
PT RotCCW(PT p,double ang) {return PT(p.x*cos(ang) - p.y*sin(ang) , p.x*sin(ang) + p.y * cos(ang));}

// project point c onto line through a and b
PT PPL (PT a,PT b,PT c){return a + (b-a)* dot(c-a,b-a) / dot(b-a,b-a);}

// project point c onto line segment through a and b
PT PPS(PT a, PT b, PT c) {
      double r = dot(b-a,b-a);
      if (fabs(r) < EPS) return a;
      r = dot(c-a, b-a)/r;
      if (r < 0) return a;
      if (r > 1) return b;
      return a + (b-a)*r;
}
// determine if lines from a to b and c to d are parallel or collinear
bool IsLP(PT a, PT b, PT c, PT d) {
      return fabs(cross(b-a, c-d)) < EPS;
}

bool IsLC(PT a, PT b, PT c, PT d) {
      return IsLP(a, b, c, d)
      && fabs(cross(a-b, a-c)) < EPS
      && fabs(cross(c-d, c-a)) < EPS;
}

// determine if line segment from a to b intersects with
// line segment from c to d
bool SGIN(PT a, PT b, PT c, PT d) {
      if (IsLC(a, b, c, d)) {
            if (dist2(a, c) < EPS || dist2(a, d) < EPS ||
                dist2(b, c) < EPS || dist2(b, d) < EPS) return true;
            if (dot(c-a, c-b) > 0 && dot(d-a, d-b) > 0 && dot(c-b, d-b) > 0)
                  return false;
            return true;
      }
      if (cross(d-a, b-a) * cross(c-a, b-a) > 0) return false;
      if (cross(a-c, d-c) * cross(b-c, d-c) > 0) return false;
      return true;
}
// compute intersection of line passing through a and b
// with line passing through c and d, assuming that unique
// intersection exists; for segment intersection, check if
// segments intersect first
PT LLIN(PT a, PT b, PT c, PT d) {
      b=b-a; d=c-d; c=c-a;
      assert(dot(b, b) > EPS && dot(d, d) > EPS);
      return a + b*cross(c, d)/cross(b, d);
}

// compute center of circle given three points
PT CCC(PT a, PT b, PT c) {
      b=(a+b)/2;
      c=(a+c)/2;
      return LLIN(b, b+RotCW90(a-b), c, c+RotCW90(a-c));
}

// determine if point is in a possibly non-convex polygon (by William
// Randolph Franklin); returns 1 for strictly interior points, 0 for
// strictly exterior points, and 0 or 1 for the remaining points.
// Note that it is possible to convert this into an *exact* test using
// integer arithmetic by taking care of the division appropriately
// (making sure to deal with signs properly) and then by writing exact
// tests for checking point on polygon boundary
bool PIPoly(const vector<PT> &p, PT q) {
      bool c = 0;
      for (int i = 0; i < p.size(); i++){
            int j = (i+1)%p.size();
            if (((p[i].y <= q.y && q.y < p[j].y) ||
                 (p[j].y <= q.y && q.y < p[i].y)) &&
                q.x < p[i].x + (p[j].x - p[i].x) * (q.y - p[i].y) / (p[j].y - p[i].y))
                  c = !c;
      }
      return c;
}

// determine if point is on the boundary of a polygon
bool POPoly(const vector<PT> &p, PT q) {
      for (int i = 0; i < p.size(); i++)
            if (dist2(PPS(p[i], p[(i+1)%p.size()], q), q) < EPS)
                  return true;
      return false;
}

// compute intersection of line through points a and b with
// circle centered at c with radius r > 0
vector<PT> CLIN(PT a, PT b, PT c, double r) {
      vector<PT> ret;
      b = b-a;
      a = a-c;
      double A = dot(b, b);
      double B = dot(a, b);
      double C = dot(a, a) - r*r;
      double D = B*B - A*C;
      if (D < -EPS) return ret;
      ret.push_back(c+a+b*(-B+sqrt(D+EPS))/A);
      if (D > EPS)
            ret.push_back(c+a+b*(-B-sqrt(D))/A);
      return ret;
}

// compute intersection of circle centered at a with radius r
// with circle centered at b with radius R
vector<PT> CCIN(PT a, PT b, double r, double R) {
      vector<PT> ret;
      double d = sqrt(dist2(a, b));
      if (d > r+R || d+min(r, R) < max(r, R)) return ret;
      double x = (d*d-R*R+r*r)/(2*d);
      double y = sqrt(r*r-x*x);
      PT v = (b-a)/d;
      ret.push_back(a+v*x + RotCCW90(v)*y);
      if (y > 0)
            ret.push_back(a+v*x - RotCCW90(v)*y);
      return ret;
}

// This code computes the area or centroid of a (possibly nonconvex)
// polygon, assuming that the coordinates are listed in a clockwise or
// counterclockwise fashion.  Note that the centroid is often known as
// the "center of gravity" or "center of mass".
double ComputeSignedArea(const vector<PT> &p) {
      double area = 0;
      for(int i = 0; i < p.size(); i++) {
            int j = (i+1) % p.size();
            area += p[i].x*p[j].y - p[j].x*p[i].y;
      }
      return area / 2.0;
}

double CAR(const vector<PT> &p) {
      return fabs(ComputeSignedArea(p));
}

PT CCN(const vector<PT> &p) {
      PT c(0,0);
      double scale = 6.0 * ComputeSignedArea(p);
      for (int i = 0; i < p.size(); i++){
            int j = (i+1) % p.size();
            c = c + (p[i]+p[j])*(p[i].x*p[j].y - p[j].x*p[i].y);
      }
      return c / scale;
}

// tests whether or not a given polygon (in CW or CCW order) is simple
bool IsSimple(const vector<PT> &p) {
      for (int i = 0; i < p.size(); i++) {
            for (int k = i+1; k < p.size(); k++) {
                  int j = (i+1) % p.size();
                  int l = (k+1) % p.size();
                  if (i == l || j == k) continue;
                  if (SGIN(p[i], p[j], p[k], p[l]))
                        return false;
            }
      }
      return true;
}





// Uses Stanford Handnote

Line Sweep Handnote

Tutorial Link : Topcoder
Please read there about the technique.
I am going to show implementation of the problems discussed there in C++.

First Problem :
Closest Pair Problem -> May be most basic implementation
Problem Link : UVA


#include <bits/stdc++.h>
using namespace std;

/*------- Constants---- */

#define Long                    long long
#define ull                     unsigned long long
#define mod                     1000000007
#define MEMSET_INF              63
#define MEM_VAL                 1061109567
#define forn(i,n)               for( int i=0 ; i < n ; i++ )
#define mp(i,j)                 make_pair(i,j)
#define lop(i,a,b)              for( int i = (a) ; i < (b) ; i++)
#define pb(a)                   push_back((a))
#define all(x)                  (x).begin(),(x).end()
#define gc                      getchar_unlocked
#define PI                      acos(-1.0)
#define INF                     1<<29
#define EPS                     1e-9
#define Fr                      first
#define Sc                      second
#define Sz                      size()
#define lc                      ((n)<<1)
#define rc                      ((n)<<1|1)
#define db(x)                   cout << #x << " -> " << x << endl;
#define Di(n)                   int n;si(n)
#define Dii(a,b)                int a,b;si(a);si(b)
#define Diii(a,b,c)             int a,b,c;si(a);si(b);si(c)
#define Si(n)                   si(n)
#define Sii(a,b)                si(a);si(b)
#define Siii(a,b,c)             si(a);si(b);si(c)
#define min(a,b)                ((a)>(b) ? (b) : (a) )
#define max(a,b)                ((a)>(b) ? (a):(b))
/*---- short Cuts ------- */
#define ms(ara_name,value) memset(ara_name,value,sizeof(ara_name))
typedef pair<int, int> ii;
typedef vector<int > vi ;
typedef vector<Long> vl;
/*------ template functions ------ */
#ifndef getchar_unlocked
#define getchar_unlocked getchar
#endif
template<class T> inline void si(T &x){register int c = gc();x = 0;int neg = 0;for(;((c<48 | c>57) && c != '-');c = gc());
      if(c=='-') {neg=1;c=gc();}for(;c>47 && c<58;c = gc()) {x = (x<<1) + (x<<3) + c - 48;}if(neg) x=-x;}
template <class T> inline T bigmod(T p,T e,T M){Long ret = 1;for(; e > 0; e >>= 1){if(e & 1) ret = (ret * p) % M;p = (p * p) % M;} return (T)ret;}
template <class T> inline T gcd(T a,T b){if(b==0)return a;return gcd(b,a%b);}
template <class T> inline T modinverse(T a,T M){return bigmod(a,M-2,M);}
void io(){freopen("/Users/MyMac/Desktop/in.txt","r",stdin);}

/*************************** END OF TEMPLATE ****************************/



const int N = 1e5+5;
struct  PT
{
      double x,y;
      PT(double _x=0,double _y=0) {x = _x, y=_y;}
      bool operator<(const PT &a) const {return x<a.x;}
      void in(){scanf(" %lf %lf",&x,&y);}
};
PT point[N];

struct ySet
{
      double y;
      int pos;
      bool operator < (const ySet & a) const{
            return y < a.y;
      }
};
double dis(PT a, PT b)
{
      double dx =a.x-b.x,dy=a.y-b.y;
      return sqrt(dx*dx+dy*dy);
      
}
int main()
{
      //io();
      int n;
      while(scanf("%d",&n) == 1 && n ) {
            forn(i,n) {
                  point[i].in();
            }
            sort(point,point + n);
            set<ySet> S;
            S.insert({point[0].y, 0}); // Set is sorted based on y co-ordinate
            double iM = 1e10;
            int L = 0;
            for(int i =1; i < n ; i ++ ) {
                  while(L < i && fabs(point[L].x - point[i].x) >= iM ) {
                        S.erase({point[L].y , L});
                        L++;
                  }
                  auto p = S.lower_bound({point[i].y - iM ,-1});
                  auto q = S.upper_bound({point[i].y + iM , n } );
                  while(p!= q) {
                        double dist = dis(point[p->pos] , point[i]);
                        iM =min(iM, dist);
                        p++;
                  }
                  S.insert({point[i].y , i} );
                  
            }
            if(iM >= 1e4) printf("INFINITY\n");
            else printf("%.4lf\n",(iM));
            S.clear();
            
      }
      return 0;
}

Lightoj – 1285 – DRAWING SIMPLE POLYGON

Link :Problem

Solution:
1. Answer is impossible only when all the points are co-linear
2. For finding the order, sort them by their polar angle in respect of pivot( The point with minimum y co-ordinate, tie breaks with minimum x co-ordinate) . If their are more than one point with same polar angle , the points which distance is smaller comes first.
3. As you can see , you can go in the sorted order, there will be no intersection, But the problem is the last polar angle.

Let’s consider the case,

5
0 0
10 0
0 1
0 2
0 3

// This is also their sorted order, As we can see, if we go with the order ,we can not make a closed polygon, To make a closed polygon, Just reverse all the point on the last polar angle

The final order would be
0 0
10 0
0 3
0 2
0 1

My code :





/*
 
 *************************
 Id  : Matrix.code
 Task:
 Date:
 
 **************************
 
 */

#include <bits/stdc++.h>
using namespace std;

/*------- Constants---- */

#define Long                    long long
#define ull                     unsigned long long
#define mod                     1000000007
#define MEMSET_INF              63
#define MEM_VAL                 1061109567
#define forn(i,n)               for( int i=0 ; i < n ; i++ )
#define mp(i,j)                 make_pair(i,j)
#define lop(i,a,b)              for( int i = (a) ; i < (b) ; i++)
#define pb(a)                   push_back((a))
#define all(x)                  (x).begin(),(x).end()
#define gc                      getchar_unlocked
#define PI                      acos(-1.0)
#define INF                     1<<29
#define EPS                     1e-9
#define Fr                      first
#define Sc                      second
#define Sz                      size()
#define lc                      ((n)<<1)
#define rc                      ((n)<<1|1)
#define db(x)                   cout << #x << " -> " << x << endl; #define Di(n) int n;si(n) #define Dii(a,b) int a,b;si(a);si(b) #define Diii(a,b,c) int a,b,c;si(a);si(b);si(c) #define Si(n) si(n) #define Sii(a,b) si(a);si(b) #define Siii(a,b,c) si(a);si(b);si(c) #define min(a,b) ((a)>(b) ? (b) : (a) )
#define max(a,b)                ((a)>(b) ? (a):(b))
/*---- short Cuts ------- */
#define ms(ara_name,value) memset(ara_name,value,sizeof(ara_name))
typedef pair<int, int> ii;
typedef vector<int > vi ;
typedef vector<Long> vl;
/*------ template functions ------ */
#ifndef getchar_unlocked
#define getchar_unlocked getchar
#endif
template<class T> inline void si(T &x){register int c = gc();x = 0;int neg = 0;for(;((c<48 | c>57) && c != '-');c = gc());
      if(c=='-') {neg=1;c=gc();}for(;c>47 && c<58;c = gc()) {x = (x<<1) + (x<<3) + c - 48;}if(neg) x=-x;}
template <class T> inline T bigmod(T p,T e,T M){Long ret = 1;for(; e > 0; e >>= 1){if(e & 1) ret = (ret * p) % M;p = (p * p) % M;} return (T)ret;}
template <class T> inline T gcd(T a,T b){if(b==0)return a;return gcd(b,a%b);}
template <class T> inline T modinverse(T a,T M){return bigmod(a,M-2,M);}
void io(){freopen("in.txt","r",stdin); freopen("out.txt","w",stdout);}

struct PT {
      int  x,y,id;
      PT(){}
      PT(int _x,int _y){x=_x,y=_y;}
      PT operator + (const PT &p) const { return PT(x+p.x , y + p.y);}
      PT operator - (const PT &p) const { return PT(x-p.x , y - p.y);}
      PT operator * (double c) const { return PT(x*c,y*c);}
      PT operator / (double c) const { return PT(x/c,y/c);}
      void input(){scanf("%d %d",&x,&y);}
};

double dot(PT p,PT q){ return p.x * q.x + p.y * q.y;}
double cross(PT p,PT q) {return p.x*q.y - p.y*q.x;}
double dist2(PT p,PT q) {return dot(p-q , p-q);}
double DIM(PT p) {return sqrt(p.x*p.x+p.y*p.y);}

/*************************** END OF TEMPLATE ****************************/
const int N = 2005;

PT point[N];
PT pivot;
bool cmp(PT a, PT b)
{
      double k = cross(a-pivot,b-pivot);
      if(fabs(k) < EPS) {
            return dist2(a,pivot) < dist2(b,pivot); } else return k > 0;
}
int main()
{
      Di(t);
      int cs = 0;
      while(t--){
            Di(n);
            forn(i,n){
                  point[i].input();
                  point[i].id = i;
            }
            int iM = point[0].y, id = 0;
            for(int i =1; i < n; i ++ ) {
                  if(point[i].y < iM || (point[i].y == iM && point[i].x < point[id].x)) { id = i; iM = point[i].y; } } swap(point[0] , point[id]); pivot = point[0]; sort(point , point + n , cmp ); int line = 0; for( line = n-2; line > 0 ; line -- ) {
                  double nn = cross(point[n-1] -pivot , point[line] - pivot );
                  if(fabs(nn) > EPS) {
                        break;
                  }
            }
            if(line == 0) printf("Case %d:\nImpossible\n", ++cs);
            else {
                  reverse(point + line+ 1, point + n );
                  printf("Case %d:\n", ++cs);
                  forn(i,n) {if(i) printf(" "); printf("%d", point[i].id);}
                  printf("\n");
            }
      }
      return 0;
}


Hill Climbing Algorithm

Discussion:
From Wiki:
In computer science, hill climbing is a mathematical optimization technique which belongs to the family of local search. It is an iterative algorithm that starts with an arbitrary solution to a problem, then attempts to find a better solution by incrementally changing a single element of the solution. If the change produces a better solution, an incremental change is made to the new solution, repeating until no further improvements can be found.

Now this algorithm can be applied to convex functions. It finds a local maximum or minimum. As we know, Ternary Search is applied to find local maximum or minimum .So I will discuss a problem , solve it using Ternary search and
again apply hill climbing algorithm to solve the maxima or minima..

Intended Problem :
Problem Link : Link
Solution :

1. Ternary Search

From the problem we , ternary search on x,y,z, like nested ternary search. Find the best possible answer



#include <bits/stdc++.h>
using namespace std;

/*------- Constants---- */

#define Long                    long long
#define ull                     unsigned long long
#define mod                     1000000007
#define MEMSET_INF              63
#define MEM_VAL                 1061109567
#define forn(i,n)               for( int i=0 ; i < n ; i++ )
#define mp(i,j)                 make_pair(i,j)
#define lop(i,a,b)              for( int i = (a) ; i < (b) ; i++)
#define pb(a)                   push_back((a))
#define all(x)                  (x).begin(),(x).end()
#define gc                      getchar_unlocked
#define PI                      acos(-1.0)
#define INF                     1<<29
#define EPS                     1e-8
#define Fr                      first
#define Sc                      second
#define Sz                      size()
#define lc                      ((n)<<1)
#define rc                      ((n)<<1|1)
#define db(x)                   cout << #x << " -> " << x << endl;
#define Di(n)                   int n;si(n)
#define Dii(a,b)                int a,b;si(a);si(b)
#define Diii(a,b,c)             int a,b,c;si(a);si(b);si(c)
#define Si(n)                   si(n)
#define Sii(a,b)                si(a);si(b)
#define Siii(a,b,c)             si(a);si(b);si(c)
#define min(a,b)                ((a)>(b) ? (b) : (a) )
#define max(a,b)                ((a)>(b) ? (a):(b))
/*---- short Cuts ------- */
#define ms(ara_name,value) memset(ara_name,value,sizeof(ara_name))
typedef pair<int, int> ii;
typedef vector<int > vi ;
typedef vector<Long> vl;
/*------ template functions ------ */
#ifndef getchar_unlocked
#define getchar_unlocked getchar
#endif
template<class T> inline void si(T &x){register int c = gc();x = 0;int neg = 0;for(;((c<48 | c>57) && c != '-');c = gc());
      if(c=='-') {neg=1;c=gc();}for(;c>47 && c<58;c = gc()) {x = (x<<1) + (x<<3) + c - 48;}if(neg) x=-x;}
template <class T> inline T bigmod(T p,T e,T M){Long ret = 1;for(; e > 0; e >>= 1){if(e & 1) ret = (ret * p) % M;p = (p * p) % M;} return (T)ret;}
template <class T> inline T gcd(T a,T b){if(b==0)return a;return gcd(b,a%b);}
template <class T> inline T modinverse(T a,T M){return bigmod(a,M-2,M);}
void IN(){    freopen("in.txt","r",stdin); freopen("out.txt","w",stdout);}


struct PT {
      double  x,y,z;
      PT(double x=0, double y=0, double z=0) : x(x), y(y) ,z(z){}
      PT(const PT &p) : x(p.x), y(p.y) ,z(p.z)  {}
      PT operator + (const PT &p) const { return PT(x+p.x , y + p.y , z+ p.z);}
      PT operator - (const PT &p) const { return PT(x-p.x , y - p.y , z - p.z);}
      PT operator * (double c) const { return PT(x*c,y*c,z*c);}
      PT operator / (double c) const { return PT(x/c,y/c,z/c);}
      void input(){scanf("%lf %lf %lf",&x,&y,&z);}
};

double dot(PT p,PT q){ return p.x * q.x + p.y * q.y + p.z * q.z ;}
double cross(PT p,PT q) {return p.x*q.y - p.y*q.x;}
double dist2(PT p,PT q) {return dot(p-q , p-q);}
double DIM(PT p) {return sqrt(p.x*p.x+p.y*p.y);}

/*************************** END OF TEMPLATE ****************************/
const int N = 1001;
int n;
PT point[N];

double calc(double x,double y, double z)
{
      double iM = 0;
      forn(i,n){
            iM = max( iM ,(dist2(point[i] , PT(x,y,z))));
      }
      return iM;
}
pair<double,double>  can1(double x,double y)
{
      double lo = -1e4, hi = 1e4 , mid , ans;
      forn(i,100){
            double f = lo + (hi - lo ) /3;
            double g = lo + 2 * (hi - lo) / 3;
            if(calc(x,y,f) < calc(x,y,g)) {
                  ans = f;
                  hi = g;
            }else { ans = g;lo = f;}
            if(fabs(lo-hi) < EPS) break;
      }
      return mp(calc(x,y,ans) ,ans );
}

typedef pair<double,double> Pair;
pair<double, pair<double,double> >  can(double x)
{
      double lo = -1e4, hi= 1e4 , mid,ans;
      forn(i,100){
            double f = lo + (hi - lo ) /3;
            double g = lo + 2 * (hi - lo) / 3;
            Pair fx = can1(x,f);
            Pair gx = can1(x,g);
            if(fx.Fr < gx.Fr) {
                  hi = g;
                  ans = f;
            }
            else {
                  lo = f;
                  ans = g;
            }
            if(fabs(lo-hi) < EPS) break;
            
      }
      Pair t = can1(x,ans);
      return mp(t.Fr , mp(ans, t.Sc));
}
int main()
{
      Si(n);
      forn(i,n) {
            point[i].input();
      }
      double lox = -1e4 , hix = 1e4 , midx, ansx = 0.0;
      Pair k;
      forn(i,100) {
            double fx = lox + (hix - lox )/ 3;
            double gx = lox + 2 * (hix - lox )/ 3;
            pair<double, pair<double,double> > f1 = can(fx);
            pair<double, pair<double,double> > f2 = can(gx);
            if(f1.Fr < f2.Fr) {
                  ansx = fx;
                  hix = gx;
                  k = f1.Sc;
            }
            else {
                  lox = fx;
                  ansx = gx;
                  k = f2.Sc;
            }
            if(fabs(lox-hix) < EPS) break;
            
      }
      
      printf("%.10lf %.10lf %.10lf\n", ansx ,k.Fr,k.Sc);
      
      return 0;
}


Now Second Solution: Hill climbing algorithm

In hill climbing algorithm, we first assume a answer, then increment this answer to the optimal answer.
We use a gradient which gradually lower down, that is the changing ratio or slope becomes smaller.
I hope after seeing the code, we will all able to understand.


#include <bits/stdc++.h>
using namespace std;

/*------- Constants---- */

#define Long                    long long
#define ull                     unsigned long long
#define mod                     1000000007
#define MEMSET_INF              63
#define MEM_VAL                 1061109567
#define forn(i,n)               for( int i=0 ; i < n ; i++ )
#define mp(i,j)                 make_pair(i,j)
#define lop(i,a,b)              for( int i = (a) ; i < (b) ; i++)
#define pb(a)                   push_back((a))
#define all(x)                  (x).begin(),(x).end()
#define gc                      getchar_unlocked
#define PI                      acos(-1.0)
#define INF                     1<<29
#define EPS                     1e-9
#define Fr                      first
#define Sc                      second
#define Sz                      size()
#define lc                      ((n)<<1)
#define rc                      ((n)<<1|1)
#define db(x)                   cout << #x << " -> " << x << endl;
#define Di(n)                   int n;si(n)
#define Dii(a,b)                int a,b;si(a);si(b)
#define Diii(a,b,c)             int a,b,c;si(a);si(b);si(c)
#define Si(n)                   si(n)
#define Sii(a,b)                si(a);si(b)
#define Siii(a,b,c)             si(a);si(b);si(c)
#define min(a,b)                ((a)>(b) ? (b) : (a) )
#define max(a,b)                ((a)>(b) ? (a):(b))
/*---- short Cuts ------- */
#define ms(ara_name,value) memset(ara_name,value,sizeof(ara_name))
typedef pair<int, int> ii;
typedef vector<int > vi ;
typedef vector<Long> vl;
/*------ template functions ------ */
#ifndef getchar_unlocked
#define getchar_unlocked getchar
#endif
template<class T> inline void si(T &x){register int c = gc();x = 0;int neg = 0;for(;((c<48 | c>57) && c != '-');c = gc());
      if(c=='-') {neg=1;c=gc();}for(;c>47 && c<58;c = gc()) {x = (x<<1) + (x<<3) + c - 48;}if(neg) x=-x;}
template <class T> inline T bigmod(T p,T e,T M){Long ret = 1;for(; e > 0; e >>= 1){if(e & 1) ret = (ret * p) % M;p = (p * p) % M;} return (T)ret;}
template <class T> inline T gcd(T a,T b){if(b==0)return a;return gcd(b,a%b);}
template <class T> inline T modinverse(T a,T M){return bigmod(a,M-2,M);}
void IN(){    freopen("in.txt","r",stdin); freopen("out.txt","w",stdout);}


struct PT {
      double  x,y,z;
      PT(double x=0, double y=0, double z=0) : x(x), y(y) ,z(z){}
      PT(const PT &p) : x(p.x), y(p.y) ,z(p.z)  {}
      PT operator + (const PT &p) const { return PT(x+p.x , y + p.y , z+ p.z);}
      PT operator - (const PT &p) const { return PT(x-p.x , y - p.y , z - p.z);}
      PT operator * (double c) const { return PT(x*c,y*c,z*c);}
      PT operator / (double c) const { return PT(x/c,y/c,z/c);}
      void input(){scanf("%lf %lf %lf",&x,&y,&z);}
};

double dot(PT p,PT q){ return p.x * q.x + p.y * q.y + p.z * q.z ;}
double cross(PT p,PT q) {return p.x*q.y - p.y*q.x;}
double dist2(PT p,PT q) {return dot(p-q , p-q);}
double DIM(PT p) {return sqrt(p.x*p.x+p.y*p.y);}

/*************************** END OF TEMPLATE ****************************/
const int N = 1001;
int n;
PT point[N];

int main()
{
      Si(n);
      forn(i,n) {
            point[i].input();
      }
      double x=0,y=0,z=0;
      double lambda = 1; // This is slope,
      forn(i,100000){
            double d = -1;
            int opt = -1;
            forn(j,n) {
                  double k = (dist2(point[j] , PT(x,y,z)));
                  if( k > d ) {
                        d = k;
                        opt = j;
                  }
            }
           // Adjusting the variables so that we go towards the optimal solution
            x+= lambda*(point[opt].x - x);
            y+= lambda* (point[opt].y - y);
            z+= lambda*(point[opt].z - z);
            lambda*= .999; // Decreasing the slope, This is important,
            
      }
      printf("%.10lf %.10lf %10lf\n", x,y,z);
      
      return 0;
}

LightOj 1118

Proble Link : http://lightoj.com/volume_showproblem.php?problem=1118
Method : Geometry

Three situation can occur.
1. The circles don’t touch each other
2. The circle touch ( Two centre can lie in different region or One’s centre can lie on others areas)
3. One circle is completely inscribed on other

Here is some input
For case 1 :



0 0 10 20 0 5

For case 2 :



0 0 10 7 0 5

For case 3:


0 0 10 3 0 3

We need to handle each of the case

1st Case : The area is ZERO.
2nd Case : Need to calculate ??
3rd Case : Area of the smaller circle

For the 2nd case , See The picture
LOJ-1118

Now Code :


//
//  main.cpp
//  1118 - Incredible Molecules
//
//  Created by Repon Macbook on 12/22/14.
//  Copyright (c) 2014 MAC. All rights reserved.
//

#include <bits/stdc++.h>
using namespace std;

/*------- Constants---- */

#define LL                      long long
#define ull                     unsigned long long
#define mod                     1000000007
#define MEMSET_INF              63
#define MEM_VAL                 1061109567
#define forn(i,n)               for( int i=0 ; i < n ; i++ )
#define mp(i,j)                 make_pair(i,j)
#define lop(i,a,b)              for( int i = (a) ; i < (b) ; i++)
#define pb(a)                   push_back((a))
#define gc                      getchar_unlocked
#define PI                      acos(-1.0)
#define inf                     1<<30
#define lc                      ((n)<<1)
#define rc                      ((n)<<1 |1)
#define db(x)                   cout << #x << " -> " << x << endl;
#define DI(n)                   int n;scanf("%d",&n)
#define DII(a,b)                int a,b;scanf("%d %d",&a,&b)
#define DIII(a,b,c)             int a,b,c;scanf("%d %d %d",&a,&b,&c)

/*---- short Cuts ------- */
#define ms(ara_name,value) memset(ara_name,value,sizeof(ara_name))
typedef pair<int, int> ii;
typedef vector<int > vi ;
/*------ template functions ------ */
#ifndef getchar_unlocked
#define getchar_unlocked getchar
#endif
inline void sc(int &x){
	register int c = gc();
	x = 0;
	int neg = 0;
	for(;((c<48 | c>57) && c != '-');c = gc());
	if(c=='-') {neg=1;c=gc();}
	for(;c>47 && c<58;c = gc()) {x = (x<<1) + (x<<3) + c - 48;}
	if(neg) x=-x;
}
template <class T> inline T bigmod(T p,T e,T M){
	LL ret = 1;
	for(; e > 0; e >>= 1){
		if(e & 1) ret = (ret * p) % M;
		p = (p * p) % M;
	} return (T)ret;
}
template <class T> inline T gcd(T a,T b){if(b==0)return a;return gcd(b,a%b);}
template <class T> inline T modinverse(T a,T M){return bigmod(a,M-2,M);}
template <class T > inline void extEuclid(T  a, T b, T &x, T &y, T &gcd) {
      x = 0; y = 1; gcd = b;
      T m, n, q, r;
      for (T u=1, v=0; a != 0; gcd=a, a=r) {
            q = gcd / a; r = gcd % a;
            m = x-u*q; n = y-v*q;
            x=u; y=v; u=m; v=n;
      }
}

// The result could be negative, if it's required to be positive, then add "m"
template <class T > inline T  modInv(T n, T m) {
      T x, y, gcd;
      extEuclid(n, m, x, y, gcd);
      if (gcd == 1) return x % m;
      return 0;
}




/*************************** END OF TEMPLATE ****************************/
const int N = 10;
struct PT{
      int x,y;
      PT(int x,int y): x(x),y(y){}
};
int sqr(int a){return a*a;}
int dist2(PT a,PT b)
{
      return sqr(a.x-b.x) + sqr(a.y-b.y);
}
int main()
{
      DI(tc);
      int cs = 0;
      while(tc--){
            DIII(x1,y1,r1);
            DIII(x2,y2,r2);
            if(r1<r2){
                  swap(x1,x2);
                  swap(y1,y2);
                  swap(r1,r2);
            }
            double d = sqrt(dist2(PT(x1,y1) , PT(x2,y2)));
            if(r1+r2 <= d ) printf("Case %d: 0\n", ++cs) ;
            else if(r1+r2 >=d &&  fabs(r1-r2) < d ) {
                  double ang1 = acos((r1*r1+d*d-r2*r2) / (2.*r1*d));
                  double ang2 = acos((r2*r2+d*d-r1*r1) / (2.*r2*d));
                  double Area = .5 * r1*r1*(2*ang1) - .5 * r1*r1*sin(2*ang1) + .5*r2*r2*(2*ang2) - .5*r2*r2*sin(2*ang2);
                  printf("Case %d: %.9lf\n" , ++cs , Area);

            }
            else {
                  double R = min(r1,r2);
                  printf("Case %d: %.9lf\n", ++cs, PI*R*R);
            }
            
      
      }
      
      return 0;
}


Geometry – Closest Pair Problem

Problem Link : http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&category=24&page=show_problem&problem=1186
Method : Divide & Conquer

//
//  main.cpp
//  10245 - The Closest Pair Problem
//
//  Created by Repon Macbook on 9/2/15.
//  Copyright (c) 2015 Repon Macbook. All rights reserved.
//

#include <bits/stdc++.h>
using namespace std;

/*------- Constants---- */

#define LL                      long long
#define ull                     unsigned long long
#define mod                     1000000007
#define MEMSET_INF              63
#define MEM_VAL                 1061109567
#define ITR(i,n)                for( int i=0 ; i < n ; i++ )
#define mp(i,j)                 make_pair(i,j)
#define lop(i,a,b)              for( int i = (a) ; i < (b) ; i++)
#define pb(a)                   push_back((a))
#define gc                      getchar_unlocked
#define PI                      acos(-1.0)
#define inf                     1<<30
#define lc                      ((n)<<1)
#define rc                      ((n)<<1 |1)
#define db(x)                   cout << #x << " -> " << x << endl;
#define DI(n)                   LL n;sc(n)
#define DII(a,b)                int a,b;sc(a);sc(b)
#define DIII(a,b,c)             int a,b,c;sc(a);sc(b);sc(c)
#define show(Ara,N)             for(int i = 0; i < N;i ++ ) printf("%d -> %d\n" , i , Ara[i])

/*---- short Cuts ------- */
#define ms(ara_name,value) memset(ara_name,value,sizeof(ara_name))
typedef pair<int, int> ii;
typedef vector<int > vi ;
/*------ template functions ------ */
#ifndef getchar_unlocked
#define getchar_unlocked getchar
#endif
inline void sc(int &x){
	register int c = gc();
	x = 0;
	int neg = 0;
	for(;((c<48 | c>57) && c != '-');c = gc());
	if(c=='-') {neg=1;c=gc();}
	for(;c>47 && c<58;c = gc()) {x = (x<<1) + (x<<3) + c - 48;}
	if(neg) x=-x;
}
template <class T> inline T bigmod(T p,T e,T M){
	LL ret = 1;
	for(; e > 0; e >>= 1){
		if(e & 1) ret = (ret * p) % M;
		p = (p * p) % M;
	} return (T)ret;
}
template <class T> inline T gcd(T a,T b){if(b==0)return a;return gcd(b,a%b);}
template <class T> inline T modinverse(T a,T M){return bigmod(a,M-2,M);}

/*************************** END OF TEMPLATE ****************************/
const int N = 1e4+5;
const int INF = 1e18;
struct PT{
      double x,y;
}Point[N];

bool cmpxy(PT a,PT b ) {
      //sorting based on x co-ordinate, then y co-ordinate
      if(a.x==b.x) return a.y < b.y;
      else return a.x < b.x;
}
bool cmpy(PT a,PT b ){
      return a.y < b.y; // sorting using y co-ordinate
}
double sqr(double a){return a*a;} // Returns square of a number
double dis(PT a,PT  b) 
{
      return sqr(a.x - b.x) + sqr(a.y - b.y) ; // Returns distance ^2 for two points
}
PT T[N];

#define EPS 1e-7
double CPP(int L,int R)
{
      // We need to calculate the CPP for Point[L] , Point [L+1] .... Point[R]
      // If L==R,Means same point, This cannot be a valid solution , Returns inf
      // If L = R-1, Only two points , We know the closest Pair distance
      if(L==R) return INF;
      if(L==R-1) return dis(Point[L], Point[R]) ;
      int mid = (L+R)/2;

      //  Split in two halfs
      double d1 = CPP(L,mid);
      double d2 = CPP(mid+1,R);
      double d = min(d1,d2);
      
      // Take the points which are nearer than d distance of Point[mid] 
      int cnt =0;
      for(int i = L;i<=R ; i++ ){
            if(sqr(Point[mid].x - Point[i].x) <= d ) {
                  T[cnt ++] = Point[i];
            }
      }
      sort(T,T+cnt , cmpy); // Sort them using y - co-ordinate
      for(int i = 0; i < cnt; i ++ ) {
            for(int j = i + 1; j < cnt && sqr(T[i].y - T[j].y ) <= d ;j ++ ) {
                  double d3 = dis(T[i] , T[j]) ; // Check if there is any pair of points
                  if(d3 < d ) d = d3;
            }
      }
      return d;
}
int main()
{
      int n;
      while(1){
            sc(n);
            if(!n) break;
            for(int i = 0 ;i < n; i ++ ) {
                  scanf("%lf %lf",&Point[i].x, &Point[i].y) ;
            }
            sort(Point ,Point+n,cmpxy) ;
            double t = CPP(0,n-1);
            if(t >= 10000 * 10000) printf("INFINITY\n");
            else printf("%.4lf\n" , (double) sqrt(t));
      }
      return 0;
}