poj1113--凸包
来源:互联网 发布:php开发ide排行榜 编辑:程序博客网 时间:2024/06/04 19:10
题目大意:poj1113
给出平面上若干个点的坐标,你的任务是建一个环形围墙,把所有的点围在里面,且距所有点的距离不小于l。求围墙的最小长度。
思路:
很容易得出答案就是凸包周长+以l为半径的圆的周长。
这里讲一下Andrew算法。
Andrew是Graham算法的变种,而且Andrew更快,且数值稳定性更好。
Andrew算法思想是先将n个点按照x坐标从小到大排序(x相同按照y从小到大),得到一个序列a1,a2,...an,将a1,a2放入ch数组,从a3开始,判断点是否在凸包当前前进方向的左边,如果是,就将点加入ch数组,否则就删除ch中的点直到在左边为止,重复上述操作。值得注意的是,Andrew需要做2次上述过程,第一次求出“下凸包”,第二次求出“上凸包”,合并起来就是完整的凸包。
具体看代码。
#include<iostream>#include<cstdio>#include<algorithm>#include<cmath>using namespace std;#define pi acos(-1.0)struct point{ int x,y; point(int x=0,int y=0):x(x),y(y){}}a[1001],ch[1001];typedef point Vector;point operator - (point a,point b){ return point(a.x-b.x,a.y-b.y);}int cross(Vector a,Vector b){ return(a.x*b.y-a.y*b.x);}double length(Vector a){ return(sqrt((double)a.x*a.x+a.y*a.y));}bool cmp(point a,point b){ return(a.x<b.x||(a.x==b.x&&a.y<b.y));}int n,i,j,k,l,x,y;double sum=0;int main(){ scanf("%d%d",&n,&l); for(i=1;i<=n;++i)scanf("%d%d",&a[i].x,&a[i].y); sort(a+1,a+n+1,cmp); int m=0; for(i=1;i<=n;++i){ while(m>1&&cross(ch[m]-ch[m-1],a[i]-ch[m-1])<0)m--; ch[++m]=a[i]; } k=m; for(i=n-1;i>=1;--i){ while(m>k&&cross(ch[m]-ch[m-1],a[i]-ch[m-1])<=0)m--; ch[++m]=a[i]; } for(i=1;i<m;++i)sum+=length(ch[i+1]-ch[i]); printf("%.0f\n",sum+2*pi*l); return 0;}
阅读全文
0 0
- POJ1113(凸包)
- poj1113 凸包
- POJ1113 Wall 凸包
- poj1113 凸包
- poj1113 凸包
- poj1113--Wall(凸包)
- POJ1113凸包
- poj1113 Wall 凸包
- poj1113 Wall --凸包
- poj1113(凸包)
- poj1113 Wall【凸包】
- poj1113--凸包
- poj1113 Wall 凸包
- 【凸包_Graham】Wall POJ1113
- POJ1113 wall 简单凸包
- POJ1113 凸包周长计算
- kyeremal-poj1113-Wall-凸包
- 凸包初学(POJ1113)
- postgresql 切换xlog日志
- poj2186--tarjan+缩点
- 自定义例外
- LA4287--tarjan
- Java并发修改异常ConcurrentModificationException
- poj1113--凸包
- 很慌
- bzoj1191 [ HNOI2006 ] --匈牙利算法
- 设备模型之kobject,kset及其关系
- bzoj1202 [ HNOI2005 ] --带权并查集
- poj1789--最小生成树
- 现在哪个公司正在招高级java
- LeetCode 1.Minimum Path Sum 2.Unique Paths I and II
- poj1228 [ SDOI2009 ] --稳定凸包