POJ 1113 Wall

27 篇文章 0 订阅
1 篇文章 0 订阅

求围墙的长度 就是里面凸包的周长+半径为L的圆周长

#include "cstring"
#include "iostream"
#include "algorithm"
#include "cstdio"
#include "queue"
#include "set"
#include "cmath"
using namespace std;
typedef long long LL;
const int M=510;
const int INF = 0x3f3f3f3f;
const double PI = acos(-1.00);
const double EPS = 1e-6;

struct point
{
	double x,y;
};
struct point a[1005],b[1005],p[2005],p1[2005];
//p:遍历全部点 p1:记录凸包的点
int size;         //凸包点个数
bool cmp(point a,point b)
{//按x从小到大排列;x相同的 按y从小到大排列
	if(a.x==b.x)
		return a.y<b.y;
	return a.x<b.x;
}
double chaji(point a,point b,point c)
{
	return (b.x-a.x)*(c.y-a.y)-(b.y-a.y)*(c.x-a.x);
}
double dist(point a,point b)
{
	return sqrt((b.x-a.x)*(b.x-a.x)+(b.y-a.y)*(b.y-a.y));
}
void sovle(int n)
{
	int i;
	double t;
	p1[0]=p[0];     //第一个凸包点是第一个点
	p1[1]=p[1]; //假设..二............二....
	size=1;    //记录当前假设的凸包点
	for(i=2;i<n;i++)//遍历所有点
	{
		t=chaji(p1[size-1],p1[size],p[i]);//算两个凸包点与该点 向量的叉积
		while(t<=0)//叉积<=0  该点不是凸包点
		{
			size--;
			if(t==0 || size==0)//垂直 或者凸包点全部遍历完
				break;
			t=chaji(p1[size-1],p1[size],p[i]);//直到该点遍历完全部凸包点或者 满足>0为凸包点
		}
		p1[++size]=p[i];//记录下一个凸包点
	}
	p1[++size]=p[n-2];
	for(i=n-3;i>=0;i--)//往回找 直到第一个凸包点
	{
		t=chaji(p1[size-1],p1[size],p[i]);
		while(t<=0)
		{
			size--;
			if(t==0 || size==0)
				break;
			t=chaji(p1[size-1],p1[size],p[i]);
		}
		p1[++size]=p[i];
	}
}
int main()
{
	int n,i;
	int l;
	double sum;
	while(~scanf("%d%d",&n,&l))
	{
		for(i=0;i<n;i++)
			scanf("%lf%lf",&p[i].x,&p[i].y);
		sort(p,p+n,cmp);
		sovle(n);
		sum=0;
		for(i=0;i<size;i++)//计算周长
			sum=sum+dist(p1[i],p1[i+1]);
		if(size==2)//若只有2个凸包点
			sum=sum/2;

		double s=PI*l*2;

		//printf("%.2lf\n",sum+s+0.5);
		printf("%d\n",int(sum+s+0.5));
	}
	return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值