[置顶] BIT 1036 篱笆长度

这题之前在poj做过,搬过来居然RE,重写了一遍

[置顶] BIT 1036 篱笆长度_第1张图片

题意就是给n个点,就是图中的实线的顶点,然后问虚线的长度

虚线要求每处距离定点都要大于r

解法,求n个点的凸包长度,再加上2*PI*r

PI是圆周率,就是答案,至于为什么,看下图就懂了

[置顶] BIT 1036 篱笆长度_第2张图片

上代码。

#include<iostream>
#include<algorithm>
#include<math.h>
#include<cstdio>
#include<stack>
#define PI acos(-1.0)
using namespace std;
class point
{
public:
	double x,y;
	void init()
	{
		scanf("%lf %lf",&x,&y);
	}
	double dist(point a)
	{
		return sqrt((a.x-x)*(a.x-x)+(a.y-y)*(a.y-y));
	}
}p[100100];
bool operator==(point a,point b)
{
	return a.x==b.x&&a.y==b.y;
}
class CVector//向量
{
public:
	double x,y;
};
CVector operator-(point a,point b)
{
	CVector ans;
	ans.x=a.x-b.x;
	ans.y=a.y-b.y;
	return ans;
}
double operator^(CVector a,CVector b)//a^b 叉积
{
	return a.x*b.y-a.y*b.x;
}
bool cmp(point a,point b)
{
	CVector VectorA=a-p[0];
	CVector VectorB=b-p[0];
	if((VectorA^VectorB)==0)
	{
		return a.x<b.x;
	}
	return (VectorA^VectorB)>0;
}
int main()//写完后对每个情况,包括1,2的特判,考虑有重复点的情况,极角相同的情况
{
	int n,r;
	while(~scanf("%d %d",&n,&r))
	{
		if(n==1)//作下特判
		{
			double x,y;
			scanf("%lf %lf",&x,&y);
			printf("%.2lf\n",2*PI*r);
			continue;
		}
		if(n==2)//作下特判
		{
			point a,b;
			a.init();
			b.init();
			printf("%.2lf\n",a.dist(b)*2+2*PI*r);
			continue;
		}
		//
		int p0i=-1;//最左最下的点
		for(int i=0;i<n;i++)
		{
			p[i].init();
			if(p0i==-1||p[i].x<p[p0i].x)
			{
				p0i=i;
				continue;
			}
			if(p[i].x==p[p0i].x&&p[i].y<p[p0i].y)
			{
				p0i=i;
			}
		}
		point tt;
		tt=p[p0i];
		p[p0i]=p[0];
		p[0]=tt;
		//最左最下的点在p[0]
		sort(p+1,p+n,cmp);//极角排序完成
		deque<point>S;
		S.push_back(p[0]);
		S.push_back(p[1]);
		for(int i=2;i<n;i++)
		{
			if(S.size()<=1)
			{
				S.push_back(p[i]);
				continue;
			}
			CVector a=S[S.size()-1]-S[S.size()-2];
			CVector b=p[i]-S[S.size()-1];
			if((a^b)>=0)
			{
				S.push_back(p[i]);
			}
			else
			{
				S.pop_back();
				i--;
			}
		}
		//凸包所有点均在S中
		double ans=0;
		for(int i=1;i<S.size();i++)
		{
			ans+=S[i].dist(S[i-1]);
		}
		ans+=S[S.size()-1].dist(p[0]);
		printf("%.2lf\n",ans+2*PI*r);
	}
	return 0;
}



你可能感兴趣的:([置顶] BIT 1036 篱笆长度)