2731: Greedyman 求凸包周长

Once there was a very greedy landlords, he found a piece of land. He then set a random number of stakes on the ground and tell people this is his land.You can assume that the stake is a circle. In order to prevent others invade the land. He decided to make a fence. Then the stakes with a rope around it as large as possible . For some reason, you owe him some money. He makes you figure out how long the rope need to buy.Remember, he is very stingy, do not want to buy more rope. If you count right, you do not owe him money. Otherwise you have to double pay.

Input

The first line of the input file contains a integer numbers N .N (3 <= N <= 1000)is the number of stakes.The radius of stakes is 1 meter.Next N lines describe coordinates of stakes in a clockwise order. Each line contains two integer numbers Xi and Yi separated by a space (-10000 <= Xi, Yi <= 10000) that represent the coordinates of ith vertex.

Output

Just print the length of rope.(2 digits after the decimal )

Sample Input

9
200 400
300 400
300 300
400 300
400 400
500 400
500 200
350 200
200 200

Sample Output

1006.28
/*
求凸包,在求其周长加上2*pi ,就可以了。比赛的以为要加(v-2)*pi,一直纠结于如何求凸包的不重复,不共线顶点上,结果悲剧了。。
*/
  1. #include <iostream>
  2. #include <cstdio>
  3. #include <cmath>
  4. #include <algorithm>
  5. #define sqr(a) ((a)*(a))
  6. #define dis2(a,b) sqrt(sqr(a.x-b.x)+sqr(a.y-b.y))
  7. using namespace std;
  8. const double pi= acos ( -1.0 );
  9. const double eps=1e -8;
  10. #define zero(x) (((x)>0?(x):-(x))<eps)
  11. struct point
  12. {
  13.     double x,y;
  14.     int operator < (point &b )
  15.     {
  16.         return ( (y<b. y|| (y==b. y && x<b. x ) ) );
  17.     }
  18.  
  19. }p [ 1005 ],ch [ 2005 ],p1,p2;
  20. int vcount ;
  21. double multi (point a , point b , point c )
  22. {
  23.     return (b. x-a. x ) * (c. y-a. y )- (b. y-a. y )* (c. x-a. x );
  24. }
  25. double xmult(point p1,point p2,point p0){
  26. return (p1. x-p0. x )* (p2. y-p0. y )- (p2. x-p0. x )* (p1. y-p0. y );
  27. }
  28.  
  29. int graham_cp ( const void* a, const void* b ) {
  30. double ret=xmult (* ( (point* )a ),* ( (point* )b ),p1 );
  31. return zero (ret )? (xmult (* ( (point* )a ),* ( (point* )b ),p2 )> 0? 1: -1 ): (ret> 0? 1: -1 );
  32. }
  33. void _graham ( int n,int& s ) {
  34. int i,k= 0;
  35. for (p1=p2=p [ 0 ],i= 1;i<n;p2. x+=p [i ]. x,p2. y+=p [i ]. y,i++ )
  36. if (p1. y-p [i ]. y>eps|| (zero (p1. y-p [i ]. y )&&p1. x>p [i ]. x ) )
  37. p1=p [k=i ];
  38. p2. x/=n,p2. y/=n;
  39. p [k ]=p [ 0 ],p [ 0 ]=p1;
  40. qsort (p +1,n -1, sizeof (point ),graham_cp );
  41. for (ch [ 0 ]=p [ 0 ],ch [ 1 ]=p [ 1 ],ch [ 2 ]=p [ 2 ],s=i= 3;i<n;ch [s++ ]=p [i++ ] )
  42. for (;s> 2&&xmult (ch [s -2 ],p [i ],ch [s -1 ] )<=-eps;s-- );
  43. }
  44.  
  45. int main ( )
  46. {
  47.     int n;
  48.     int stack [ 10000 ],top;
  49.  
  50.     while ( scanf ( "%d",&n )!= EOF )
  51.     {
  52.         for ( int i= 0 ; i<n ; i++ )
  53.          scanf ( "%lf%lf",&p [i ]. x,&p [i ]. y );
  54.         _graham (n,top );
  55.         double c= 0.0;
  56.         for ( int i= 1 ; i<=top ; i++ )
  57.          c+=dis2 (ch [i -1 ],ch [i%top ] );
  58.          int tt=top;
  59.         //for ( int i=0 ; i<top ; i++ )
  60.          //printf("%.1lf %.1lf ",ch[i].x,ch[i].y);
  61.         for ( int i= 0 ; i<top ; i++ )
  62.          if (!multi (ch [i ],ch [ (i +1 )%top ],ch [ (i +2 )%top ] ) )
  63.           tt--;
  64.          for ( int i= 1 ; i<top ; i++ )
  65.           if (ch [i ]. x==ch [ 0 ]. y && ch [i ]. y == ch [ 0 ]. y )
  66.            tt++;
  67.          c+= 2*pi;
  68.         printf ( "%.2lf/n",c );
  69.  
  70.     }
  71. }

你可能感兴趣的:(2731: Greedyman 求凸包周长)