标签:
二维凸包模板
p[1010]//输入的点集,res[1010]//输出的点集
int n;//点的个数
int cmp(Point a,Point b)//先对x坐标排序,在比较y坐标
{
if(a.x==b.x)
return a.y<b.y;
return a.x<b.x;
}
int ConvexHull()//返回凸包顶点数
{
sort(p,p+n,cmp);
int m=0;
for(int i=0;i<=n-1;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(n>1)//起始点重复
m--;
return m;
}
for(int i=0;i<=m-2;i++)//求凸包的长度
sum+=length(res[i],res[i+1]);
sum+=length(res[0],res[m-1]);
poj 1113
Description
Input
Output
Sample Input
9 100 200 400 300 400 300 300 400 300 400 400 500 400 500 200 350 200 200 200
Sample Output
1628
#include<iostream>
#include<cstring>
#include<cstdio>
#include<cmath>
#include<vector>
#include<string>
#include<algorithm>
#define LL long long
#define inf 0x3f3f3f3f
using namespace std;
const double pi=atan(1.0)*4;
struct Point
{
double x;
double y;
}p[1010],res[1010];
int n;
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)//向量a,b的叉积,在二维坐标系下是一个数
{
return a.x*b.y-a.y*b.x;
}
int cmp(Point a,Point b)
{
if(a.x==b.x)
return a.y<b.y;
return a.x<b.x;
}
int ConvexHull()//返回凸包顶点数
{
sort(p,p+n,cmp);
int m=0;
for(int i=0;i<=n-1;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(n>1)//起始点重复
m--;
return m;
}
double length(Point a,Point b)
{
return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));
}
int main()
{
int l;
cin>>n>>l;
for(int i=0;i<=n-1;i++)
cin>>p[i].x>>p[i].y;
int m=ConvexHull();
double sum=0;
for(int i=0;i<=m-2;i++)
sum+=length(res[i],res[i+1]);
sum+=length(res[0],res[m-1]);
sum+=2*pi*l;
printf("%.0lf\n",sum);
return 0;
}
标签:
原文地址:http://blog.csdn.net/winycg/article/details/51335429