HDU 1392 Surround the Trees (Graham求凸包周长)

时间:2022-02-24 14:09:53

题目链接

题意 : 让你找出最小的凸包周长 。

思路 : 用Graham求出凸包,然后对每条边求长即可。

Graham详解

 #include <stdio.h>
#include <string.h>
#include <iostream>
#include <math.h>
#include <algorithm> using namespace std ; struct point
{
int x,y ;
}p[],p1[];
int n ; double dis(point a,point b)
{
return sqrt(double((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y))) ;
}
double cross(point a,point b,point c)
{
return (a.x-c.x)*(b.y-c.y) - (a.y-c.y)*(b.x-c.x) ;
}
bool cmp(point a,point b)
{
if(cross(a,b,p[]) > || cross(a,b,p[]) == && dis(a,p[]) < dis(b,p[]))
return true ;
return false ;
}
void Graham()
{
int cnt;
sort(p+,p+n,cmp) ;
p[n] = p[] ;
p1[] = p[] ;
p1[] = p[] ;
cnt = ;
for(int i = ; i <= n ; i++)
{
while(cnt >= && cross(p1[cnt-],p1[cnt],p[i]) <= ) cnt -- ;
p1[ ++cnt] = p[i] ;
}
double sum = 0.0 ;
for(int i = ; i < cnt ; i++)
{
sum += dis(p1[i],p1[i+]) ;
//printf("*%.2lf*\n",sum) ;
}
printf("%.2lf\n",sum) ;
}
int main()
{
while(~scanf("%d",&n) && n)
{
int pos = ;
for(int i = ; i < n ; i++)
{
scanf("%d %d",&p[i].x,&p[i].y) ;
if(p[pos].y > p[i].y || (p[pos].y == p[i].y && p[i].x < p[pos].x))
pos = i ;
}
if(n == ) {puts("0.00");continue ;}
if(n == )
{
printf("%.2lf\n",dis(p[],p[])) ;
continue ;
}
swap(p[pos],p[]) ;
//printf("%d %d\n",p[0].x,p[0].y) ;
Graham() ;
}
return ;
}