您的位置:首页 > 其它

poj 1113 Wall

2014-05-02 19:07 274 查看
题目链接:http://poj.org/problem?id=1113

题目大意:给出点集和一个长度L,要求用最短长度的围墙把所有点集围住,并且围墙每一处距离所有点的距离最少为L,求围墙的长度。

解法:凸包+以L为半径的圆的周长。以题目中的图为例,两点之间的围墙长度之和正好就是凸包的长度,再加上每个点的拐角处(注意此处为弧,才能保证城墙距离点的距离最短)的长度。

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<algorithm>
#define inf 0x7fffffff
#define exp 1e-10
#define PI 3.141592654
using namespace std;
int n,L;
struct Point
{
double x,y;
Point (double x=0,double y=0):x(x),y(y){}
friend bool operator < (Point a,Point b)
{
if (a.x!=b.x) return a.x<b.x;
return a.y<b.y;
}
}an[1000+10],bn[1000+10];
typedef Point Vector;
Vector operator + (Vector A,Vector B) {return Vector(A.x+B.x , A.y+B.y); }
Vector operator - (Vector A,Vector B) {return Vector(A.x-B.x , A.y-B.y); }
Vector operator * (Vector A,double p) {return Vector(A.x*p , A.y*p); }
int dcmp(double x)
{
if (fabs(x)<exp) return 0;
else return x<0 ? -1 : 1;
}
double cross(Vector A,Vector B)
{
return A.x*B.y-B.x*A.y;
}
int ConvexHull(Point *p,int n,Point *ch)
{
sort(p,p+n);
int m=0;
for (int i=0 ;i<n ;i++)
{
while (m>1 && dcmp(cross(ch[m-1]-ch[m-2],p[i]-ch[m-1]))<=0) m--;
ch[m++]=p[i];
}
int k=m;
for (int i=n-2 ;i>=0 ;i--)
{
while (k>m && dcmp(cross(ch[k-1]-ch[k-2],p[i]-ch[k-1]))<=0) k--;
ch[k++]=p[i];
}
ch[k++]=ch[0];
if (n>1) k--;
return k;
}
int main()
{
while (cin>>n>>L)
{
for (int i=0 ;i<n ;i++)
scanf("%lf%lf",&an[i].x,&an[i].y);

int k=ConvexHull(an,n,bn);
double sum=0;
sum += 2*PI*L;
for (int i=0 ;i<k ;i++)
{
sum += sqrt((bn[i].x-bn[i+1].x)*(bn[i].x-bn[i+1].x)+(bn[i].y-bn[i+1].y)*(bn[i].y-bn[i+1].y));
}
printf("%.0f\n",sum);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: