您的位置:首页 > 其它

zoj 1453 Surround the Trees(求凸包周长)

2015-04-23 08:39 387 查看
题目地址

题目大意:给出n个点及n个点的坐标,求将所有点包围住的最短长度

解题思路:裸凸包问题

#include <iostream>
#include <cstdio>
#include <cmath>
#include <cstring>
#include <algorithm>
#include <queue>
#include <string>
#include <map>
#include <stack>
#include <list>

using namespace std;

const int maxn = 1000+10;
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){}
bool operator == (const Point& A)const
{
return dcmp(x-A.x)==0 && dcmp(y-A.y)==0;
}
bool operator < (const Point& A)const
{
return dcmp(x-A.x)<0 || dcmp(x-A.x)==0;
}
};

Point p[maxn],ch[maxn];
typedef Point Vector;

Vector operator - (Point A,Point B)
{
return Vector(A.x-B.x,A.y-B.y);
}

double Cross(Vector A,Vector B)
{
return A.x*B.y-A.y*B.x;
}

int ConvexHull(Point *p,int n,Point *ch) //求凸包
{
sort(p,p+n);
n = unique(p,p+n)-p; //非重复点的个数
int m = 0;
for(int i = 0; i < n; i++)
{
while(m>1 && Cross(ch[m-1]-ch[m-2], p[i]-ch[m-2])<=0)
m--;
ch[m++]=p[i];
}
int k = m;
for(int i = n-2; i >= 0; i--)
{
while(m > k && Cross(ch[m-1]-ch[m-2], p[i]-ch[m-2])<=0) m--;
ch[m++] = p[i];
}
if(n>1) m--;
return m;
}

int main()
{
int n;
while(scanf("%d",&n) != EOF)
{
if(!n)  break;
for(int i = 0; i < n; i++)
scanf("%lf%lf",&p[i].x,&p[i].y);
int m = ConvexHull(p,n,ch);
double ans = 0;
ch[m] = ch[0];
for(int i = 0; i < m; i++)
ans += sqrt((ch[i].x-ch[i+1].x)*(ch[i].x-ch[i+1].x)+(ch[i].y-ch[i+1].y)*(ch[i].y-ch[i+1].y));
printf("%.2lf\n",ans);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: