Poj1113

Poj1113

   有这么一个城堡,它的俯视平面图由一堆柱子组成(不要问我为什么),然后问这个城堡最小需要的围墙长度。

解:画个图就比较清楚了,去掉所有圆弧,将剩余边进行平移,恭喜你一个凸包就在你眼前。接下来的问题就完全是数学问题了,我选择用水平序算法去求凸包。

水平序算法实际上就是做两遍凸壳,拼在一起就是个包了。

听起来很简单对不对,可是我还就是写错了。

第一遍写水平序忽视了队列为空是不能弹出元素的。Orz..

解决方法:l=0;r=-1; (l<=r)的情况下队列为空。

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<cstring>
#define eps 1e-10
#define MAXN 1005
const double Pi=acos(-1.0);
using namespace std;
struct point{
	double x,y;
	point(){x=y=0;}
	point(double _x,double _y){x=_x;y=_y;}
}T[MAXN];
int Q[MAXN*2];
bool cmp(point a,point b){return a.x==b.x?a.y<b.y:a.x<b.x;}
point V(point start,point end){return point(end.x-start.x,end.y-start.y);}

double Cross(point a,point b){return a.x*b.y-b.x*a.y;}

double dis(point a,point b){return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));}

int n;double L;
int main(){
	double ans=0;int l,r;
	scanf("%d%lf",&n,&L);
	for(int i=1;i<=n;i++) scanf("%lf%lf",&T[i].x,&T[i].y);
	sort(T+1,T+n+1,cmp);
	l=0,r=-1;
	for(int i=1;i<=n;i++){
		while(l<r&&Cross(V(T[Q[r-1]],T[Q[r]]),V(T[Q[r]],T[i]))>eps) r--;
		Q[++r]=i;
	}
	for(int i=l;i<r;i++) ans+=dis(T[Q[i]],T[Q[i+1]]);
	memset(Q,0,sizeof(Q));
	l=0,r=-1; 
	for(int i=n;i>=1;i--){
		while(l<r&&Cross(V(T[Q[r-1]],T[Q[r]]),V(T[Q[r]],T[i]))>eps) r--;
		Q[++r]=i;
	}for(int i=l;i<r;i++) ans+=dis(T[Q[i]],T[Q[i+1]]);
	ans+=2*L*Pi;
	printf("%d\n",(int)(ans+0.5));
	return 0;
} 


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值