POJ 1113 入门凸包

来源:互联网 发布:淘宝挂机软件是真的吗 编辑:程序博客网 时间:2024/05/17 06:18

自己的第一法凸包
思路就是,建立凸包,求凸包周长加上圆的周长,主要练模版

#include <iostream>#include <cstdio>#include <cstring>#include <algorithm>#include <cmath>const double eps=1e-8;const double PI=acos(-1);const int maxn=1000+10;int N,L;int top;using namespace std;int sgn(double x){    if(fabs(x)<eps)        return 0;    if(x>0)        return 1;    if(x<0)        return -1;}struct point{    int x,y;    point() {}    point(int _x,int _y){        x=_x;        y=_y;    }};typedef point vector;vector operator + (vector A,vector B){    return point(A.x+B.x,A.y+B.y);}vector operator - (point A,point B){    return point(A.x-B.x,A.y-B.y);}int operator ^ (vector A,vector B){    return A.x*B.y-A.y*B.x;}int operator * (vector A,vector B){    return A.x*B.x+A.y*B.y;}bool operator < (vector A,vector B){    return A.x<B.x || A.x==B.x && A.y<B.y;}bool operator == (point a,point b){    return sgn(a.x-b.x)==0 && sgn(a.y-b.y)==0;}double dis(point a,point b){    return hypot(a.x-b.x,a.y-b.y);}struct convex{    int n;    point p[maxn];};convex t;point p[maxn];bool cmp(point a,point b){ //极角排序函数        int d=(a-p[0])^(b-p[0]);        if(d==0&&sgn(dis(a,p[0])-dis(b,p[0])) < 0 || d>0)//共线时取较近的点            return true;        return false;}void init(){   //找到初始点    for(int i=0;i<N;i++)        if(p[i]<p[0])            swap(p[i],p[0]);}void graham(int n)   //graham-scan{    n=N;    if(n==1){        top=1;        t.p[0]=p[0];    }    else if(n==2){        top=2;        t.p[0]=p[0];t.p[1]=p[1];        if(t.p[0]==t.p[1])            top--;    }    else{        t.p[0]=p[0];t.p[1]=p[1];        top=2;        for(int i=2;i<n;i++){            while(top>1 && sgn((t.p[top-1]-t.p[top-2])^(p[i]-t.p[top-2])) <= 0)                  top--;            t.p[top]=p[i];            top++;        }    }}double solve(){    double res=2*PI*L;    init();    sort(p+1,p+N,cmp);    graham(N);    /*for(int i=0;i<top;i++)        printf("(%d,%d)\n",t.p[i].x,t.p[i].y);*/    for(int i=0;i<top;i++)        res+=dis(t.p[i],t.p[(i+1)%top]);    return res;}int main(){    //freopen("input.txt","r",stdin);    while(~scanf("%d%d",&N,&L)){        double res;        for(int i=0;i<N;i++){            int x,y;            scanf("%d%d",&x,&y);            p[i]=point(x,y);        }        res=solve();        printf("%d\n",int(res+0.5));    }    return 0;}
0 0
原创粉丝点击