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,3if(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;elsecout<<","<<(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;elsecout<<","<<(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 secondint 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 cross(b-a, c-a);} // 判向
double get_dis(Point a, Point b)
{double dx = a.x - b.x;double dy = a.y - b.y;return sqrt(dx * dx + dy * dy);
}int n,top;
bool vis[110];
Point pt[10010];
int stk[10010];
void Graham()
{sort(pt+1, pt+1+n);top = 0;int ck;for(int i=1;i<=n;i++){while(top>1 && (ck = sign(area(pt[stk[top-1]], pt[stk[top]], pt[i]))) <= 0){vis[stk[top]] = 0;top--;}stk[++top] = i;vis[i] = 1;}vis[1] = 0;for(int i=n;i>=1;i--){if(vis[i]) continue;while(top>1 && sign(area(pt[stk[top-1]], pt[stk[top]], pt[i])) <= 0)top--;stk[++top] = i;}if(stk[top]==1) top--;
}
bool check()
{for(int i=1;i<=n;i++){for(int j=i+1;j<=n;j++){for(int k=j+1;k<=n;k++){if(sign(area(pt[i], pt[j], pt[k])) == 0)return 1;}}}return 0;
}
void solve()
{n = 0;char c;double x,y;while(scanf("%lf,%lf",&x, &y)!=EOF){pt[++n] = {x,y};scanf("%c",&c);}if(check()){cout<<"ERROR"<<endl;return ;}Graham();if(top!=n)cout<<"ERROR"<<endl;else{Point cc = {0,0};int k = 1;for(int i=2;i<=top;i++){if(get_dis(pt[stk[i]],cc) < get_dis(pt[stk[k]],cc))k = i;}for(int i=1;i<=top;i++){printf("%.0lf,%.0lf",pt[stk[k]].x, pt[stk[k]].y);if(i!=top) printf(",");k--;if(k==0) k = top;}}
}
int main()
{freopen("data.in","r",stdin); solve();return 0;
}