HDU3685 几何+重心+凸包+判定锐角三角形

先算重心!!!!!!再算凸包!!!!!!!

View Code
  1 /*
  2 几何+重心
  3 */
  4 #include<stdio.h>
  5 #include<string.h>
  6 #include<stdlib.h>
  7 #include<algorithm>
  8 #include<iostream>
  9 #include<queue>
 10 //#include<map>
 11 #include<math.h>
 12 using namespace std;
 13 typedef long long ll;
 14 //typedef __int64 int64;
 15 const int maxn = 50005;
 16 const int inf = 0x7fffffff;
 17 const double pi=acos(-1.0);
 18 const double eps = 1e-8;
 19 struct point {
 20     double x,y;
 21     bool operator < ( const point &l ) const {
 22      return y<l.y||( l.y==y&&x<l.x );
 23 }
 24 };
 25 struct point2{
 26     double x,y,area;
 27 };
 28 point myp[ maxn ],res[ maxn ];
 29 point2 b[ maxn ];//由一个三角形得到的新“点“
 30 
 31 double xmult( point sp,point ep,point op ){
 32      return (sp.x - op.x) * (ep.y - op.y)-(ep.x - op.x) * (sp.y - op.y);
 33 }
 34 
 35 int graham( int n,point pnt[] ){
 36       int i, len, k = 0;
 37       int top = 1;
 38       sort(pnt, pnt + n);
 39       if (n == 0) return 0; res[0] = pnt[0];
 40       if (n == 1) return 1; res[1] = pnt[1];
 41       if (n == 2) return 2; res[2] = pnt[2];
 42       for (i = 2; i < n; i++) {
 43           while (top && xmult(res[ top ], pnt[ i ], res[top-1])>=0 )//( cross : from top to i )
 44               top--;
 45           res[++top] = pnt[i];
 46       }
 47       len = top; res[++top] = pnt[n - 2];
 48       for (i = n - 3; i >= 0; i--) {
 49           while (top!=len && xmult(res[ top ], pnt[ i ], res[top-1])>=0 ) 
 50           top--;
 51           res[++top] = pnt[i];
 52       }
 53       return top; // 返回凸包中点的个数
 54  }//res 存储着凸包里面的点
 55 
 56 point get_grav( int n,point p[] ){
 57     double ans_x,ans_y;
 58     double sum_Area=0;
 59     int cnt=0;//被切割为三角形的个数
 60     for( int i=2;i<n;i++ ){
 61         double tmp=xmult( p[ i-1 ],p[ i ],p[ 0 ] );
 62         b[ cnt ].x=p[ 0 ].x+p[ i-1 ].x+p[ i ].x;
 63         b[ cnt ].y=p[ 0 ].y+p[ i-1 ].y+p[ i ].y;
 64         b[ cnt ].area = tmp;
 65         sum_Area += tmp;
 66         cnt++;
 67     }
 68     ans_x=ans_y=0;
 69     for( int i=0;i<cnt;i++ ){
 70         ans_x+=b[ i ].x*b[ i ].area;
 71         ans_y+=b[ i ].y*b[ i ].area;
 72     }
 73     ans_x/=(3.0*sum_Area);
 74     ans_y/=(3.0*sum_Area);//重心坐标
 75     point grav;
 76     grav.x=ans_x,grav.y=ans_y;
 77     return grav;//返回重心坐标
 78 }
 79 double dist( point a,point b ){
 80     return (a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y);
 81 }
 82 bool solve( point a,point b,point now ){//判断会不会出现钝角
 83     double dis1,dis2,dis3;
 84     dis1 = dist( a,b );
 85     dis2 = dist( a,now );
 86     dis3 = dist( b,now );
 87     if( (dis1+dis2-dis3>eps)&&(dis1+dis3-dis2>eps) ) 
 88         return true;//这两个角必须为锐角,才可能保证 now 这个点在a,b“之间“
 89     return false;
 90 }
 91     
 92 int main(){
 93     int ca;
 94     scanf("%d",&ca);
 95     while( ca-- ){
 96         int n;
 97         scanf("%d",&n);
 98         for( int i=0;i<n;i++ )
 99             scanf("%lf%lf",&myp[ i ].x,&myp[ i ].y);
100         point grav;
101         grav = get_grav( n,myp );
102         int CNT = graham( n,myp );
103         //printf("CNT:%d\n",CNT);
104         //for( int i=0;i<CNT;i++ )
105             //printf("%d:%lf %lf\n",i,res[i].x,res[i].y);
106         //printf("grav:%lf %lf\n",grav.x,grav.y);
107         int ans=0;
108         res[ CNT ]=res[ 0 ];
109         for( int i=1;i<=CNT;i++ ){
110             if( solve( res[i-1],res[i],grav )==true )
111                 ans++;//,printf("ans:%d %d\n",i-1,i);
112         }
113         printf("%d\n",ans);
114     }
115     return 0;
116 }    
keep moving...
原文地址:https://www.cnblogs.com/xxx0624/p/2969895.html