UVALive 4639&&SPOJ SPOINTS&&POJ 3805&&AOJ 1298 Separate Points

10436 단어 live
https://icpcarchive.ecs.baylor.edu/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=2640
http://www.spoj.com/problems/SPOINTS/en/
http://poj.org/problem?id=3805
http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=1298
한 직선 으로 두 개의 돌출 된 가방 을 나 누 려 면,두 개의 돌출 된 가방 이 서로 교차 하지 않 고,서로 어 울 리 지 않 는 것 이 필요 하 다.
템 플 릿 이 없 는 상황 에서 제 코드 는 poj,uva,spoj 를 넘 었 지만 aoj 를 넘 지 못 하고 정확 한 코드 와 촬영 에서 발 견 된 상황 이 사실 에 부합 되 지 않 습 니 다.
방법 은:
1.각 점 이 볼록 가방 이나 가장자리 에 있 는 지 판단
2.두 개의 돌출 된 가방 이 두 라인 마다 교차 하 는 지 판단 한다.
#include <cstdio>

#include <cstring>

#include <algorithm>

#include <cmath>

using namespace std;

const double eps=1e-8;

const int  maxn=205;

int dcmp(double d){

    if(fabs(d)<eps)return 0;

    return d>0?1:-1;

}

struct pnt{

    double x,y;

    pnt():x(0),y(0){}

    pnt(double tx,double ty):x(tx),y(ty){}

    pnt operator -(pnt p2){

        pnt newp(x-p2.x,y-p2.y);

        return newp;

    }

    pnt operator +(pnt p2){

        pnt newp(x+p2.x,y+p2.y);

        return newp;

    }

    pnt operator *(double  d){

        pnt newp(x*d,y*d);

        return newp;

    }

    pnt operator /(double  d){

        pnt newp(x/d,y/d);

        return newp;

    }

    double dis(pnt p2){

        return sqrt((x-p2.x)*(x-p2.x)+(y-p2.y)*(y-p2.y));

    }

    bool operator ==(pnt p2){

        if(dcmp(x-p2.x)==0&&dcmp(y-p2.y)==0)return true;

        return false;

    }

};

double cross(pnt p1,pnt p2){

    return p1.x*p2.y-p1.y*p2.x;

}

bool cmpx(pnt p1,pnt p2){

    if(p1.x!=p2.x)return p1.x<p2.x;

    return p1.y<p2.y;

}

pnt base;

bool cmp(pnt p1,pnt p2){

    return cross(p1-  base,p2-base)<0;

}



int isPointInConvexPolygon(pnt p1,pnt * p,int n){

    for(int i=0;i<n;i++){

        pnt A=pnt(p[(i+1)%n].x-p[i].x,p[(i+1)%n].y-p[i].y);

        pnt B=pnt(p1.x-p[i].x,p1.y-p[i].y);

        int fl=dcmp(cross(A,B));

        if(fl<0)return 0;

        if(fl==0){

            int maxx=max(p[(i+1)%n].x,p[i].x);

            int minx=min(p[(i+1)%n].x,p[i].x);

            int maxy=max(p[(i+1)%n].y,p[i].y);

            int miny=min(p[(i+1)%n].y,p[i].y);

            if(minx<=p1.x&&maxx>=p1.x&&miny<=p1.y&&maxy>=p1.y)return -1;//on the edge

            else return 0;

        }

    }

    return 1;

}

int graham(pnt * p,pnt * h,int n){



        int m=0;

        for(int i=0;i<n;i++){//     

                while(m>1&&cross((h[m-1]-h[m-2]),(p[i]-h[m-2]))<=0){m--;}

                h[m++]=p[i];

        }

        int tm=m;

        for(int i=n-2;i>=0;i--){//     

                while(m>tm&&cross((h[m-1]-h[m-2]),(p[i]-h[m-2]))<=0){m--;}

                h[m++]=p[i];

        }

        if(n>1)m--;

        return m;

}



bool between(pnt p1,pnt p2,pnt p){

        return (p.x<=max(p1.x,p2.x)&&p.x>=min(p1.x,p2.x))

        &&  (p.y<=max(p1.y,p2.y)&&p.y>=min(p1.y,p2.y));

}

bool isInsert(pnt p11,pnt p12,pnt p21,pnt p22){

        pnt v=p22-p21;

        pnt w=p12-p11;

        pnt u=p21-p11;

        if(cross(v,w)==0){

                if(cross(v,u)!=0)return false;

                if(between(p11,p12,p21))return true;

                if(between(p11,p12,p22))return true;

                return false;

        }

        double t=cross(w,u)/cross(v,w);

        double t2=cross(v,u)/cross(v,w);

        if(t2>1||t2<0)return false;

        if(t>1||t<0)return false;

        return true;

}



pnt bp[maxn],bh[maxn],wp[maxn],wh[maxn];

int bn,wn,btop,wtop;



int main(){

        while(scanf("%d%d",&bn,&wn)==2&&(bn||wn)){

                for(int i=0;i<bn;i++){

                        scanf("%lf%lf",&bp[i].x,&bp[i].y);

                }

                for(int i=0;i<wn;i++){

                        scanf("%lf%lf",&wp[i].x,&wp[i].y);

                }

                bool fl=true;



                if(bn>1){

                        sort(bp,bp+bn,cmpx);

                        base =bp[0];

                        sort(bp+1,bp+bn,cmp);

                        btop=graham(bp,bh,bn);



                        if(fl)for(int i=0;i<wn;i++){

                                if(isPointInConvexPolygon(wp[i],bh,btop)){

                                        fl=false;

                                        break;

                                }

                        }

                }



                if(wn>1){

                        sort(wp,wp+wn,cmpx);

                        base =wp[0];

                        sort(wp+1,wp+wn,cmp);

                        wtop=graham(wp,wh,wn);





                        if(fl){

                                for(int i=0;i<bn;i++){

                                        if(isPointInConvexPolygon(bp[i],wh,wtop)){

                                                fl=false;

                                                break;

                                        }

                                }

                        }

                }



                if(fl&&bn>1&&wn>1){

                        for(int i=0;i<btop;i++){

                                for(int j=0;j<wtop;j++){

                                        if(isInsert(bh[i],bh[(i+1)%btop],wh[j],wh[(j+1)%wtop])){

                                                fl=false;

                                                break;

                                        }

                                }

                        }

                }

                if(wn==1&&bn==1&&bp[0]==wp[0]){fl=false;}





                if(fl)puts("YES");

                else puts("NO");

        }

        return 0;

}


이곳 의 코드 는 모두 통과 할 수 있다.
#include<iostream>

#include<cstdio>

#include<algorithm>

#include<cmath>

#include<map>

#include<vector>

#include<queue>

#include<functional>

#include<cstring>

#include<cstdlib>

#include<complex>

using namespace std;

typedef long long ll;

typedef complex < double > Point;



typedef vector < Point > Polygon;

namespace std {

    bool operator < (Point a,Point b) {

        return real(a) != real(b) ? real(a) < real(b) : imag(a) < imag(b);

    }

}

const double EPS = 1e-8;

const double INF = 1e12;







struct Line : Polygon{

    Line(){};

    Line(Point p,Point q){ push_back(p);push_back(q); }

};

double cross(Point p,Point q){

    return imag(conj(p)*q);

}

double dot(Point p,Point q){

    return real(conj(p)*q);

}



int ccw(Point a,Point b,Point c){

    b-=a,c-=a;

    if(cross(b,c)>0)return 1; //    り

    if(cross(b,c)<0)return -1; //   り

    if(dot(b,c)<0)return 2; //   に c - a - b

    if(norm(b)<norm(c))return -2; //    に a - b - c

    return 0; //    に a - c - b

}



bool intersectSS(Line s, Line t) {

    return ccw(s[0],s[1],t[0])*ccw(s[0],s[1],t[1]) <= 0 &&

         ccw(t[0],t[1],s[0])*ccw(t[0],t[1],s[1]) <= 0;

}

bool intersectSP(Line s, Point p) {

    return abs(s[0]-p)+abs(s[1]-p)-abs(s[1]-s[0]) < EPS; // triangle inequality

}

Polygon ConvexHull(Polygon ps) {//  

    int n = ps.size(), k = 0;

    if(n == 1)return ps;

    sort(ps.begin(), ps.end());

    Polygon ch(2*n);

    for (int i = 0; i < n; ch[k++] = ps[i++]) // lower-hull

        while (k >= 2 && ccw(ch[k-2], ch[k-1], ps[i]) <= 0) --k;

    for (int i = n-2, t = k+1; i >= 0; ch[k++] = ps[i--]) // upper-hull

        while (k >= t && ccw(ch[k-2], ch[k-1], ps[i]) <= 0) --k;

    ch.resize(k-1);

    return ch;

}



// Point - Vertex

enum{OUT, ON, IN};

int IsInnerPointVertex(Polygon ps,Point a){

    bool flg = false;

    for(int i = 0;i < ps.size();i++){

        Point p = ps[i] - a,q = ps[(i+1)%ps.size()] - a;

        if(imag(p)>imag(q))swap(p,q);

        if(imag(p)<=0&&0<imag(q)){

            if(cross(p,q) < 0)flg = !flg;

        }

        if(cross(p,q) == 0 && dot(p,q) <= 0)return ON;

    }

    return flg ? IN : OUT;

}

int main(){

    int n,m;

    while(cin>>n>>m,n){

        Polygon G,H;

        for(int i = 0;i < n;i++){

            double x,y;

            cin>>x>>y;

            G.push_back(Point(x,y));

        }

        for(int i = 0;i < m;i++){

            double x,y;

            cin>>x>>y;

            H.push_back(Point(x,y));

        }

        G = ConvexHull(G);

        H = ConvexHull(H);

        int g = G.size(),h = H.size();

        //cout<<g<<" "<<h<<endl;

        if(g > h)swap(G,H);

        g = G.size(),h = H.size();

        bool flg = true;

        for(int i = 0;i < g;i++){

            if(IsInnerPointVertex(H,G[i]) != OUT){

                flg = false;

                break;

            }

        }

        for(int i = 0;i < h;i++){

            if(IsInnerPointVertex(G,H[i]) != OUT){

                flg = false;

                break;

            }

        }



        if(h == 1)flg = true;

        else if(g == 1 && h == 2){

            flg = !(intersectSP(Line(H[0],H[1]),G[0]));

        }

        else if(g == 2 && h == 2){

            flg = !(intersectSS(Line(G[0],G[1]),Line(H[0],H[1])));

        }

        else if(g == 2){

            flg = true;

            for(int i = 0;i < h;i++){

                int j = (i+1)%h;

                if(intersectSS(Line(G[0],G[1]),Line(H[i],H[j])))flg = false;

            }

        }

        if(flg)cout<<"YES"<<endl;

        else cout<<"NO"<<endl;

    }

    return 0;

}


좋은 웹페이지 즐겨찾기