您的位置:首页 > 其它

POJ 1113 凸包周长

2013-02-14 20:28 162 查看
题意:

国王想建一个周长最短的城墙,使墙的任意一点到城墙的距离都 大于 rr。求这面墙的周长。

题解:

凸包 水平序graham扫描法

显然答案就是:凸包的周长+半径为rr的圆的周长

View Code

#include <iostream>
#include <cstdlib>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <cmath>

#define N 1010
#define EPS 1e-7
#define PI 3.1415926535

using namespace std;

struct PO
{
double x,y;
}p
;

double rr,ans;
int n,stk
;

inline bool cmp(const PO &a,const PO &b)
{
if(a.x==b.x) return a.y<b.y;
return a.x<b.x;
}

inline void read()
{
scanf("%d%lf",&n,&rr);
for(int i=1;i<=n;i++) scanf("%lf%lf",&p[i].x,&p[i].y);
}

inline double cross(const PO &o,const PO &a,const PO &b)
{
return (a.x-o.x)*(b.y-o.y)-(b.x-o.x)*(a.y-o.y);
}

inline double get_dis(const PO &a,const PO &b)
{
return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));
}

inline void graham()
{
sort(p+1,p+1+n,cmp);
int top=0;
stk[++top]=1; stk[++top]=2;
for(int i=3;i<=n;i++)
{
while(top>=2&&cross(p[stk[top-1]],p[stk[top]],p[i])<EPS) top--;
stk[++top]=i;
}
int num=top;
for(int i=n-1;i>=1;i--)
{
while(top>num&&cross(p[stk[top-1]],p[stk[top]],p[i])<EPS) top--;
stk[++top]=i;
}
ans=0.0;
for(int i=1;i<top;i++) ans+=get_dis(p[stk[i]],p[stk[i+1]]);
}

inline void go()
{
graham();
ans+=2.0*rr*PI;
printf("%.0lf\n",ans+EPS);
}

int main()
{
read(),go();
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: