hdu 1392 Surround the Trees(凸包)

来源:互联网 发布:免费进销存 知乎 编辑:程序博客网 时间:2024/05/17 12:46

题意:有很多树,现在要用绳子包围起来,问最小的长度?

注意:(1)只有1个点的时候,输出0;

           (2) 如果所有点都在一条直线上,那么不需要包围起来。

#include <iostream>#include <cstdio>#include <cstring>#include <string>#include <algorithm>#include <stack>#include <cmath>#include <vector>#include <queue>#include <map>#include <set>using namespace std;#define LL long long#define M 1002#define DEBUG puts("It's here!")#define INF 1<<29#define PI acos(-1.0)#define CLS(x,v) memset(x,v,sizeof(x))#define FOR(i,w,n)  for(int i=(w);i<=(n);++i)struct point{    int x,y;    void input()    {        scanf("%d%d",&x,&y);    }    point() {}    point(int vx,int vy)    {        x=vx;        y=vy;    }    point operator -(const point &b)    {        return  point(x-b.x,y-b.y);    }} p[M];int cross(point a,point b ){    return a.x*b.y-a.y*b.x;}double dist(point a){    return sqrt(1.0*a.x*a.x+a.y*a.y);}int cmp(point a,point b){    int ret=cross(a-p[0],b-p[0]);    if(ret==0)return dist(a-p[0])>dist(b-p[0]);    else return ret>0;}int st[M],cnt;int n,flag;void graham(){    int k=0,i;    for(i=1; i<n; i++)        if(p[i].x<p[k].x||(p[i].x==p[k].x&&p[i].y<p[k].y))        {            k=i;        }    swap(p[0],p[k]);    sort(p+1,p+n,cmp);    cnt=0;i=2;    st[cnt]=0;    st[++cnt]=1;    while(i<n)    {        while(cnt>1&&cross(p[st[cnt]]-p[st[cnt-1]],p[i]-p[st[cnt]])<0)            cnt--;        st[++cnt]=i++;    }    if(flag==0)st[++cnt]=0;//如果不在一条直线上就要圈回来    double ans=0.0;    for(i=1; i<=cnt; i++)    {  // printf("-->%d %d\n",p[st[i]].x,p[st[i]].y);        ans+=dist(p[st[i]]-p[st[i-1]]);    }    printf("%.2lf\n",ans);}bool allInline(){    for(int i=2;i<n;i++)    if(cross(p[1]-p[0],p[i]-p[0]))    {        return 0;    }    return 1;}int main(){    while(~scanf("%d",&n)&&n)    {        flag=0;        for(int i=0; i<n; i++)        {            p[i].input();        }        if(n<=1){printf("0.00\n");continue;}        if(allInline())flag=1;//判断是否在一条线上        graham();    }    return 0;}


0 0