POJ 1113 Wall 【凸包入门】

13 篇文章 0 订阅
4 篇文章 0 订阅

原题连接:http://poj.org/problem?id=1113

题意:给 n 个点,你见一个围墙,使所有的点到围墙的距离不小于 l 。求围墙长度。。

思路:先求出n个点的 凸包,然后根据凸包建一个围墙,围墙的一部分就是 凸包长度,另一部分 是一个 以 l 为半径的 圆!!

代码:

#include<stdio.h>
#include<string.h>
#include<math.h>
#include<algorithm>
using namespace std;
int m,top;
struct point
{
	int x,y;
}P[2000],S[2000],T;

void find_pole_point() //找到基点 交换到 0 
{
	int i,j=0;
	T=P[0];
	for(i=1;i<m;i++)
	{
		if(P[i].y<T.y||(P[i].y==T.y&&P[i].x<T.x))
		{
			j=i;
			T=P[i];
		}
	}
	T=P[0];
	P[0]=P[j];
	P[j]=T;
}

double dis(point t1,point t2) //计算两点距离
{
	double z=(t1.x-t2.x)*(t1.x-t2.x)+(t1.y-t2.y)*(t1.y-t2.y);
	return sqrt(z);
}

double cross(point t1,point t2,point t3,point t4) //向量叉积
{
	return (t2.x-t1.x)*(t4.y-t3.y)-(t2.y-t1.y)*(t4.x-t3.x);
}

bool cmp(point t1,point t2)
{
	double z= cross(P[0],t1,P[0],t2);
	return z? z>0:dis(P[0],t1)>dis(P[0],t2);
}

void scanner() //求凸包
{
	int i,j;
	find_pole_point();
	sort(P+1,P+m,cmp);
	S[0]=P[0];
	S[1]=P[1];
	top=1;
	for(i=2;i<m;i++)
	{
		while(cross(S[top-1],S[top],S[top],P[i])<0)
			top--;
		top++;
		S[top]=P[i];
	}
}

int main()
{
	int i,j,ncase,l;
	while(scanf("%d%d",&m,&l)!=EOF)
	{
		for(i=0;i<m;i++)
			scanf("%d%d",&P[i].x,&P[i].y);
		scanner();
		double ans= 2*3.1415926*l;
        for(i=0;i<=top;i++)
		    ans+= dis(S[i],S[(i+1)%(top+1)]);
	     printf("%.0lf\n",ans);
    }
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值