B Convex Polygon

Posted Jozky86

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了B Convex Polygon相关的知识,希望对你有一定的参考价值。

B Convex Polygon

题意:

有n个点,每两个点组成一个坐标,现在问你是否所有的点可以构成一个凸多边形。并且这些点应该以顺时针方向输出。

题解:

很明显裸的凸包板子题,但是我们队里没人负责计算几何,当时抄的kuangbin板子,太啰嗦了,以后应该自己整理 ,然后又调了半小时
也算是复习一下凸包了
我们以为判断全了,结果忘了特判是不是所有点参与构成凸包,而错失八题

代码:

比赛代码:

#include<bits/stdc++.h>
using namespace std;
const int maxp=1020;
const double eps=1e-8;
const double pi=acos(-1.0);
typedef pair<int,int> pii;
#define x first
#define y second
#define double int
int sgn(double x){
	if(fabs(x)<eps)return 0;
	if(x<0)return -1;
	else return 1;
}
struct Point{
	double x,y;
	Point(){
	}
	Point(double _x,double _y){
		x=_x;
		y=_y;
	}
	bool operator==(Point b)const{
		return sgn(x-b.x)==0&&sgn(y-b.y)==0;
	}
	bool operator<(Point b)const{
		return sgn(x-b.x)==0?sgn(y-b.y)<0:x<b.x;
	}
	Point operator+(const Point &b)const {
		return Point(x+b.x,y+b.y);
	}
	Point operator-(const Point &b)const {
		return Point(x-b.x,y-b.y);
	}
	double operator^(const Point &b)const {
		return x*b.y-y*b.x; 
	}
	double distance(Point p){
		return hypot(x-p.x,y-p.y);
	}
	
};
struct Line{
	Point s,e;
	Line(){}
	Line(Point _s,Point _e){
		s=_s;
		e=_e;
	}
	bool operator==(Line v){
		return (s==v.s)&&(e==v.e);
	}
	Line(Point p,double angle){
		s=p;
		if(sgn(angle-pi/2)==0){
			e=(s+Point(0,1));
		}
		else {
			e=(s+Point(1,tan(angle)));
		}
	}
	Line(double a,double b,double c){
		if(sgn(a)==0){
			s=Point(0,-c/b);
			e=Point(1,-c/b);
		}
		else if(sgn(b)==0){
			s=Point(-c/a,0);
			e=Point(-c/a,1);
		}
		else {
			s=Point(0,-c/b);
			e=Point(1,(-c-a)/b);
		}
	}

};
const int N=110;
pii q[N];
int n;
struct polygon{
	int n;
	Point p[maxp];
	Line l[maxp];
	void input(int jcy){
		n=jcy;
//		cout<<n<<endl;
		for(int i=0;i<n;i++){
			p[i]=Point(q[i+1].x*1.0,1.0*q[i+1].y);
//			cout<<p[i].x<<" "<<p[i].y<<endl;
//			p[i].input();
		}
	}
	void getline(){
		for(int i=0;i<n;i++){
			l[i]=Line(p[i],p[(i+1)%n]);
		}
	} 
	struct cmp{
		Point p;
		cmp(const Point &p0){
			p=p0;
		}
		bool operator()(const Point &aa,const Point &bb){
			Point a=aa,b=bb;
			int d=sgn((a-p)^(b-p));
			if(d==0){
				return sgn(a.distance(p)-b.distance(p))<0;
			}
			return d>0;
		}
	};
	
	void norm(){
		Point mi=p[0];
		for(int i=1;i<n;i++)mi=min(mi,p[i]);
		sort(p,p+n,cmp(mi));
	}
	void getconvex(polygon &convex){
		sort(p,p+n);
		convex.n=n;
//		for(int i=0;i<n;i++)	cout<<p[i].x<<" "<<p[i].y<<endl;
//		cout<<n<<endl;
		for(int i=0;i<min(n,2);i++){
			convex.p[i]=p[i];
//			cout<<convex.p[i].x<<endl;`````````````````````````````````````````````````````
		}
		if(convex.n==2&&(convex.p[0]==convex.p[1]))convex.n--;
		if(n<=2)return ;
		int &top=convex.n;
		top=1;
		for(int i=2;i<n;i++){
			while(top&&sgn((convex.p[top]-p[i])^(convex.p[top-1]-p[i]))<=0){
				top--;
			}
			convex.p[++top]=p[i];
		}
		int temp=top;
		convex.p[++top]=p[n-2];
		for(int i=n-3;i>=0;i--){
			while(top!=temp&&sgn((convex.p[top]-p[i])^(convex.p[top-1]-p[i]))<=0){
				top--;
			}
			convex.p[++top]=p[i];
		}
		if(convex.n==2&&(convex.p[0]==convex.p[1]))convex.n--;
//		convex.norm();
	}
}P;

pii get(int a,int b,int c,int d){
	int dy=d-b;
	int dx=c-a;
	int dd=__gcd(dx,dy);
	dy/=dd;
	dx/=dd;
	if(dy<0)	dy*=-1,dx*=-1;
	return {dy,dx};
}
signed main (){
	
	int cnt=0;
	int x,y;
	string s;	
	cin>>s;
	vector<int>v;
	int res=0;
	int tot=0;
	for(int i=0;i<s.size();i++){
		if(s[i]==','){
			continue;
		}
		tot++;
		int j=i;
		int f=1;
		
		while(j<s.size()&&s[j]!=','){//1,1,1,3,-1,3
			if(s[j]=='-')		f*=-1;
			else{
				res=res*10+s[j]-'0';		
			}
			j++;
		}
		i=j-1;
//		cout<<res*f<<endl;
		v.push_back(f*res);
		res=0;
	}
	if(v.size()&1)
	{
		cout<<"ERROR";
		return 0;
	}
	int D=1010;
	for(int i=0;i<v.size();i+=2){
		q[++n]={v[i]+D,v[i+1]+D};
	}
	if(n<=2){
		cout<<"ERROR";
		return 0;
	}
	for(int i=1;i<=n;i++){
		for(int j=1;j<=n;j++){
			for(int k=1;k<=n;k++)
			if(i!=j && j!=k && i!=k){
				if(get(q[i].x,q[i].y,q[j].x,q[j].y)==get(q[j].x,q[j].y,q[k].x,q[k].y)){
					cout<<"ERROR";
					return 0;
				}
			}
		}
	}
//	cout<<n<<endl;
	P.input(n);
	P.getline(); 
	polygon tt;
	P.getconvex(tt);
	double dist=1e18;
	int id=0;
//	cout<<tt.n<<endl;
	if(tt.n!=tot/2){
		cout<<"ERROR";
		return 0;
	}
	for(int i=0;i<tt.n;i++)
	{
		tt.p[i].x-=D;
		tt.p[i].y-=D;
//		cout<<tt.p[i].x<<' '<<tt.p[i].y<<endl;
		if(tt.p[i].x*tt.p[i].x+tt.p[i].y*tt.p[i].y<dist)
		{
			dist=min(dist,tt.p[i].x*tt.p[i].x+tt.p[i].y*tt.p[i].y);
			id=i;
		}
	}
	vector<pii>vv;
//	cout<<id<<endl;
	bool flag=false;
	for(int i=id;i<tt.n;i++)
	{
		double x=tt.p[i].x;
		double y=tt.p[i].y;
		if(!flag)
		cout<<(int)x<<","<<(int)y,flag=true;
		else
		cout<<","<<(int)x<<","<<(int)y;
	}
	for(int i=0;i<id;i++)
	{
		double x=tt.p[i].x;
		double y=tt.p[i].y;

		if(!flag)
		cout<<(int)x<<","<<(int)y,flag=true;
		else
		cout<<","<<(int)x<<","<<(int)y;
	}
//	for(int i=0;i<vv.size();i++){
//		
//		cout<<vv[i].x<<","<<vv[i].y;
//		if(i!=vv.size()-1)
//		cout<<",";
		if(i!=(int)vv.size()-1)
//		
//	}
//	
}

赛后代码:

#include<bits/stdc++.h>
using namespace std;

const double eps = 1e-12;
#define Point pair<double,double>
#define x first
#define y second

int sign(double x)
{
	if(fabs(x) < eps) return 0;
	return x<0 ? -1:1;
}
Point operator-(Point a, Point b) {return {a.x-b.x, a.y-b.y};} // 向量 
double cross(Point a, Point b) {return a.x * b.y - b.x * a.y;} // 叉积 
double area(Point a, Point b, Point c) {return crossLeetcode: Convex Polygon

[LeetCode] Convex Polygon 凸多边形

LeetCode469 - Convex Polygon - Medium (Python)

poj1259The Picnic & hdu6219 Empty Convex Polygon(17沈阳区域赛C)最大空凸包

记录shapely包的Polygon的self.wkt

R语言为散点图添加凸包(convex hull):数据预处理(创建一个包含每组数据凸包边界的数据集)ggplot2使用geom_polygon函数为可视化图像添加凸包(convex hull)