LightOJ1203->求凸包最小内角角度

来源:互联网 发布:java while sleep 编辑:程序博客网 时间:2024/05/07 17:25

LightOJ1203


题意:

被转化后的问题其实就是求凸包最小的内角角度。

题解:

构造一个凸包,通过余弦定理遍历所有内角,求出最小角度。

代码:

#include <stdio.h>#include <iostream>#include <cmath>#include <algorithm>#include <float.h>using namespace std ;#define MAX 100005#define PI acos(-1.0)const double eps = 1e-8 ;int sgn(double x){    if(fabs(x) < eps) return 0 ;    if(x < 0) return -1 ;    else return 1 ;}struct Point{    double x , y ;    Point(){}    Point(double _x , double _y)    {        x = _x ; y = _y ;    }    Point operator - (const Point &b) const    {        return Point(x - b.x , y - b.y) ;    }    double operator ^ (const Point &b) const    {        return x*b.y - y*b.x ;    }    double operator * (const Point &b) const    {        return x*b.x + y*b.y ;    }};bool mult(Point sp,Point ep,Point op){  return (sp.x - op.x) * (ep.y - op.y) >= (ep.x - op.x) * (sp.y - op.y);}bool operator < (const Point &l, const Point &r){   return l.y < r.y ||(l.y == r.y && l.x < r.x);}Point list[MAX] ;Point Stack[MAX] ;int top ;int Graham(Point pnt[],int n, Point res[])//构造凸包{  int i,len ,k = 0,top = 1;  sort(pnt,pnt+n);  if(n == 0)return 0; res[0] = pnt[0];  if(n == 1)return 1; res[1] = pnt[1];  if(n == 2)return 2; res[2] = pnt[2];  for(int i =2; i < n; ++ i){    while(top && mult(pnt[i],res[top],res[top-1]))        top--;    res[++top] = pnt[i];  }  len = top; res[++top] = pnt[n - 2];  for(i = n - 3; i >= 0; -- i){    while(top!=len && mult(pnt[i],res[top],res[top-1]))        top--;    res[++top] = pnt[i];  }  return top;//返回凸包中点的个数}double len(Point A,Point B)//返回向量AB的模{  return hypot(A.x-B.x,A.y-B.y);}double dot(Point A,Point B,Point C)//点乘{  return (C.x-A.x)*(B.x-A.x)+(C.y-A.y)*(B.y-A.y);}double get(Point A,Point B,Point C)//余弦定理{  return acos(dot(A,B,C)/len(A,B)/len(A,C));}double minangle()//遍历凸包所有点,余弦定理求角{  if(top < 3) return 0;  double ans = 2 * PI;  Stack[top] = Stack[0];Stack[top+1] = Stack[1];  for(int i = 1; i<= top; ++ i){    ans = min(ans,get(Stack[i],Stack[i+1],Stack[i-1]));  }  return ans/PI*180;}int main(){    int T ,n ,a , b;    scanf("%d" , &T) ;    for(int cas = 1 ; cas <= T ; cas ++)    {        scanf("%d" , &n) ;        for(int i = 0 ; i < n ; i ++)        {            scanf("%lf%lf" , &list[i].x,&list[i].y) ;        }        top = Graham(list ,n , Stack) ;        printf("Case %d: %.10f\n" , cas , minangle()) ;    }    return 0 ;}/*4425 882512 -762-572 -942647 -651091 973-980 -668-509 993295 -144-524 397-925 278-720 584-34 358-815 922-655 -834-126006026 -879795176-47582593 -89523275 -272575414-458441662 515814-285 157597519980485785 763819290-496900235 -476020953-900802943 283817053-375048494 -663706092-664553421 9601-9224 -923287608137739042 -429347330729407623 -105134941774 -498256533-546543123 -761186661-136235155 -1527981621159 -8360-938193474 223721588Case 1: 51.420756489Case 2: 64.330894519Case 3: 32.422781562Case 4: 57.490203768*/
0 0
原创粉丝点击