UVALive 3218

#include<cstdio>
#include<cmath>
#include<vector>
#include<map>
#include<algorithm>
#include<iostream>
#define X 100010
#define eps 1e-6
#define pi 3.14159265358979323
using namespace std;
struct point{
    double x,y;
    point(){x=0.0;y=0.0;}
    ~point(){}
}p[110],q[X],s[X];
int sign(double x){
    return x<-eps?-1:x>eps;
}
double det(point a,point b,point c){
    return (c.x-a.x)*(b.y-a.y)-(c.y-a.y)*(b.x-a.x);
}
double dot(point a,point b,point c){
    return (c.x-a.x)*(b.x-a.x)+(c.y-a.y)*(b.y-a.y);
}
double dis(point a,point b){
    return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));
}
bool operator <(point a,point b){
    return sign(a.x-b.x)<0||sign(a.x-b.x)==0&&sign(a.y-b.y)<0;
}
bool operator ==(point a,point b){
    return sign(a.x-b.x)==0&&sign(a.y-b.y)==0;
}
bool operator !=(point a,point b){
    return !(a==b);
}
bool on(point a,point b,point c){
    return a.x>min(b.x,c.x)-eps&&a.y>min(b.y,c.y)-eps
         &&a.x<max(b.x,c.x)+eps&&a.y<max(b.y,c.y)+eps;
}
bool insrt(point u1,point u2,point v1,point v2,point& ans){
    ans=u1;
    double t=((u1.x - u2.x)*(v1.y - v2.y) - (u1.y - u2.y)*(v1.x - v2.x));
    if(sign(t)==0)return 0;
    t=((u1.x - v1.x)*(v1.y - v2.y) - (u1.y - v1.y)*(v1.x - v2.x))/t;
    ans.x += (u2.x - u1.x)*t;
    ans.y += (u2.y - u1.y)*t;
    return on(ans,u1,u2)&&on(ans,v1,v2);
}
vector<int>e[X];
map<point,int>h;
int hn;
void hash(point u){
    if(!h[u]){
        q[hn]=u;
        h[u]=hn++;
    }
}
point cmpp,cmpq;
bool cmp(point a,point b){
    return dis(a,cmpp)<dis(b,cmpp);
}
void makeedge(int n){
    int i,j,u,v,m;
    point jd;
    for(i=1;i<=n;i++){
        m=0;
        for(j=1;j<=n;j++)if(j!=i&&j!=i+1&&j!=i-1){
            if(i==1&&j==n||i==n&&j==1)continue;
            if(insrt(p[i],p[i+1],p[j],p[j+1],jd)){
                s[m++]=jd;
                hash(jd);
            }
        }
        cmpp=p[i];
        s[m++]=p[i];
        s[m++]=p[i+1];
        sort(s,s+m,cmp);
        m=unique(s,s+m)-s;
        for(j=1;j<m;j++){
            u=h[s[j]];v=h[s[j-1]];
            e[u].push_back(v);
            e[v].push_back(u);
        }
    }
}
double cal(int a){
    return atan2(det(cmpq,cmpp,q[a]),dot(cmpq,cmpp,q[a]));
}
int pn;
point st;
int main(){
    int i,j,k,n,u,v;
    double base,ang,best;
    while(~scanf("%d",&n)){
        hn=1;pn=0;
        h.clear();
        for(i=0;i<X;i++)e[i].clear();
        for(i=1;i<=n;i++){
            scanf("%lf%lf",&p[i].x,&p[i].y);
            hash(p[i]);
        }
        if(n<3){
            printf("%d\n",n);
            for(i=1;i<=n;i++)
                printf("%.4lf %.4lf\n",p[i].x,p[i].y);
            continue;
        }
        p[n+1]=p[1];
        makeedge(n);
        u=h.begin()->second;
        best=10;
        for(i=0;i<e[u].size();i++){
            j=e[u][i];
            ang=atan2(q[j].y-q[u].y,q[j].x-q[u].x);
            if(ang<best){best=ang;v=j;}
        }
        pn=1;st=s[0]=q[u];
        while(q[v]!=st){
            s[pn++]=q[v];
            best=10;
            base=atan2(q[u].y-q[v].y,q[u].x-q[v].x);
            for(i=0;i<e[v].size();i++){
                j=e[v][i];if(j==u)continue;
                ang=atan2(q[j].y-q[v].y,q[j].x-q[v].x)-base;
                if(sign(ang)<0)ang+=2*pi;
                if(sign(ang-2*pi)>0)ang-=2*pi;
                if(ang<best){
                    best=ang;
                    k=j;
                }
            }
            u=v;v=k;
        }
        printf("%d\n",pn);
        for(i=0;i<pn;i++)
            printf("%.4lf %.4lf\n",s[i].x,s[i].y);
    }
    return 0;
}

你可能感兴趣的:(UVALive 3218)