二维凸包模板
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; } <p>注意:当图为两个点时,直接输出这两个点的长度,下式会不成立</p> 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; }