hdu1392——凸包模板
题意:求给出点的凸包周长
注意:n==2时,输出两点连线长度即可
AC代码:
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<string>
#include<stack>
#include<map>
#include<queue>
#include<set>
#include<cmath>
#include<cstdlib>
//#include<bits/stdc++.h>
using namespace std;
#define scan(n) scanf("%d",&n)
#define scand(n) scanf("%lf",&n)
#define ll long long
#define eps 1e-8
struct point
{
double x,y;
point() {
} point(double _x,double _y)
{
x=_x;
y=_y;
}
point operator - (const point &b) const
{
return point(x-b.x,y-b.y);
}
bool operator < (const point &b) const
{
return x<b.x||x==b.x&&y<b.y;
}
}res[120005],p[120005];
//res:得到的凸包的点
//p:原点数组
typedef point Vector;//向量
int n;//原点个数
int dcmp(double x)
{
return (x>eps)-(x<-eps);
}
double cross(Vector a,Vector b)//求向量叉乘
{
return a.x*b.y-b.x*a.y;
}
int andrew()
{
sort(p,p+n);
int m=0;
for (int i=0; i<n; i++)
{
while(m>1&&cross(res[m-1]-res[m-2],p[i]-res[m-2])<0)
--m;
res[m++]=p[i];
}
int k=m;
for (int i=n-2; i>=0; --i)
{
while (m>k&&cross(res[m-1]-res[m-2],p[i]-res[m-2])<0)
--m;
res[m++]=p[i];
}
if (m>1)
--m;
return m;//m:凸包中点的个数(下标从0到m-1)
}
int main()
{
int i;
double r;
while(scan(n)&&n)
{
for(i=0;i<n;i++)
{
scand(p[i].x);
scand(p[i].y);
}
if(n==2)
{
printf("%.2f\n",sqrt((p[1].x-p[0].x)*(p[1].x-p[0].x)+(p[1].y-p[0].y)*(p[1].y-p[0].y)));
continue;
}
int num=andrew();
r=0;
for(i=0;i<num-1;i++)
{
r+=sqrt((res[i+1].x-res[i].x)*(res[i+1].x-res[i].x)+(res[i+1].y-res[i].y)*(res[i+1].y-res[i].y));
}
r+=sqrt((res[0].x-res[num-1].x)*(res[0].x-res[num-1].x)+(res[0].y-res[num-1].y)*(res[0].y-res[num-1].y));
printf("%.2f\n",r);
}
return 0;
}