UVA 1396

来源:互联网 发布:淘宝买号 编辑:程序博客网 时间:2024/05/22 10:51
书上的题目,开始跟着新的大神了= =
#include<cstdio>#include<cstring>#include<algorithm>#include<cmath>using namespace std;//精度控制const double eps=1e-10;int dcmp(double x){    if(fabs(x)<eps) return 0;    return x<0?-1:1;}//点struct Point{    double x,y;    Point(){}    Point(double x,double y):x(x),y(y){}};//向量typedef Point Vector;//点-点==向量Vector operator-(Point A,Point B){    return Vector(A.x-B.x,A.y-B.y);}//向量+向量==向量 或 点+向量==点Vector operator+(Vector A,Vector B){    return Vector(A.x+B.x,A.y+B.y);}//向量*实数==向量Vector operator*(Vector A,double p){    return Vector(A.x*p,A.y*p);}//求向量长度double Length(Vector v){    return sqrt(v.x*v.x+v.y*v.y);}//返回v逆时针旋转90度的单位向量Vector Normal(Vector v){    double L=Length(v);    return Vector(-v.y/L, v.x/L);}//叉积double Cross(Vector A,Vector B){    return A.x*B.y-A.y*B.x;}//直线struct Line{    Point p;    Vector v;    double ang;    Line(){}    Line(Point p,Vector v):p(p),v(v)    {        ang=atan2(v.y,v.x);    }    bool operator<(const Line &L)const    {        return ang<L.ang;    }};//判断p是否在直线L左边(在直线上不算)bool OnLeft(Line L,Point p){    return Cross(L.v,p-L.p)>0;}//得到直线的交点Point GetIntersection(Line a,Line b){    Vector u=a.p-b.p;    double t=Cross(b.v,u)/Cross(a.v,b.v);    return a.p+a.v*t;}//求直线集合L构成的半平面交集,如果存在是一个凸包int HalfplaneIntersection(Line *L,int n,Point *poly){    //极角排序    sort(L,L+n);    int first=0,last=0;    Point *p=new Point[n];    Line *q=new Line[n];    q[0]=L[0];    for(int i=1;i<n;i++)    {        //删除尾部无效节点        while(first<last && !OnLeft(L[i],p[last-1])) last--;        //删除头部无效节点        while(first<last && !OnLeft(L[i],p[first])) first++;        //插入新直线        q[++last]=L[i];        //如果新插入的直线与last直线平行,需要删除最右边的那条        if(fabs(Cross(q[last].v,q[last-1].v))<eps)        {            last--;            if(OnLeft(q[last],L[i].p)) q[last]=L[i];        }        //新插入直线与上一条直线构成last-1交点        if(first<last) p[last-1]=GetIntersection(q[last-1],q[last]);    }    //同first直线排序尾部无效节点    while(first<last && !OnLeft(q[first],p[last-1])) last--;    //半平面不构成有界区域    if(last-first<=1 ) return 0;    //求首直线与尾直线交点    p[last]=GetIntersection(q[last],q[first]);    int m=0;    for(int i=first;i<=last;i++) poly[m++]=p[i];    return m;}const int N=101;int n;Point p[N],poly[N];Vector v1[N],v2[N];Line l[N];int main(){    while(scanf("%d",&n)&&n){        for(int i=0;i<n;i++){            scanf("%lf%lf",&p[i].x,&p[i].y);        }        for(int i=0;i<n;i++){            v1[i]=p[(i+1)%n]-p[i];            v2[i]=Normal(v1[i]);        }        double left=0,right=1e8;        while((right-left)>1e-7){            double mid=(right+left)/2;            for(int i=0;i<n;i++){                l[i]=Line(p[i]+v2[i]*mid,v1[i]);            }            int m=HalfplaneIntersection(l,n,poly);            if(!m)right=mid;            else left=mid;        }        printf("%.6lf\n",left);    }    return 0;}

0 0
原创粉丝点击