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. }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值