Graham #1Wa求助
查看原帖
Graham #1Wa求助
289304
HAuCl4楼主2023/1/8 22:35

RT,所有点都在x轴上,但是随机微小扰动也无法解决。

#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define db double
const db eps=1e-9;
inline int sgn(db a) {return a<-eps?-1:a>eps;}
inline int cmp(db a,db b){return sgn(a-b);}
//点或向量
struct P{
	db x,y;
	P operator +(P p){return {x+p.x,y+p.y};}
	P operator -(P p){return {x-p.x,y-p.y};}
//	P operator *(db d){return {x*d,y*d};}
	db operator *(P p){return x*p.y-y*p.x;}
	P operator /(db d){return {x/d,y/d};}
	bool operator <(const P& p) const{
		int c=cmp(x,p.x);
		if(c) return c==-1;
		return cmp(y,p.y)==-1;
	}
	bool operator ==(const P& o) const{
		return cmp(x,o.x)==0 && cmp(y,o.y)==0;
	}
	db dot(P p){return x*p.x+y*p.y;}
//	db det(P p){return x*p.y-y*p.x;}
	//一些函数
	db abs2(){return x*x+y*y;}
	db abs() {return sqrt(abs2());}
	db distTo(P p) {return (*this-p).abs();}
	db alpha() {return atan2(y,x);}
	void read() {cin>>x>>y;if(rand()%2) x+=eps;if(rand()%2) y+=eps;}
	void write(){printf("(%lf,%lf)\n",x,y);}
	P rot90() {return P{-y,x};}
	P unit() {return *this/abs();}
	int quad() const{
		return sgn(y)==1 || (sgn(y)==0&&sgn(x)>=0);
	}//判断象限 
};
#define cross(p1,p2,p3) ((p2.x-p1.x)*(p3.y-p1.y)-(p3.x-p1.x)*(p2.y-p1.y))
#define crossOp(p1,p2,p3) sgn(cross(p1,p2,p3))//折线方向 
P tmp;
bool cmp1(P a,P b)
{
	return (a-tmp).alpha()<(b-tmp).alpha();
}
vector<P> convexHull(int n,P *ps)
{
	vector<P> qs(n*2);
	if(n<=1)
	{
		qs.resize(1);
		qs[0]=ps[0];
		return qs;
	}
	sort(ps,ps+n);
	tmp=ps[0];
//	tmp.write();
	sort(ps,ps+n,cmp1);
	int k=0;
	for(int i=0;i<n;qs[k++]=ps[i++])
		while(k>1 && crossOp(qs[k-2],qs[k-1],ps[i])<=0) --k;
	for(int i=n-2,t=k;i>=0;qs[k++]=ps[i--])
		while(k>t && crossOp(qs[k-2],qs[k-1],ps[i])<=0) --k;
	qs.resize(k-1);
	return qs;
} 
int n;
P a[100005];
int main()
{
//	freopen("P2742_1.in","r",stdin);
	srand(time(0));
	scanf("%d",&n);
	vector<P> out;
	for(int i=0;i<n;i++)
		a[i].read();
	out=convexHull(n,a);
	int k=out.size();
//	for(int i=0;i<k;i++) out[i].write();
	db ans=0;
	for(int i=0;i<k-1;i++) ans+=(out[i+1]-out[i]).abs();
	ans+=(out[0]-out[k-1]).abs();
	printf("%.2lf",ans);
//	for(int i=0;i<k;i++) out[i].write();
	return 0;
}
2023/1/8 22:35
加载中...