zoukankan      html  css  js  c++  java
  • UVALive 4639 && SPOJ SPOINTS && POJ 3805 && AOJ 1298 Separate Points 求两个凸包是否相交 难度:3

    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;
    }
    

      这里的代码都可以过:http://pelkira.hatenablog.jp/

    #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;
    }
    

      

  • 相关阅读:
    聊聊WS-Federation
    用双十一的故事串起碎片的网络协议(上)
    责任链模式的使用-Netty ChannelPipeline和Mina IoFilterChain分析
    最小化局部边际的合并聚类算法(中篇)
    最小化局部边际的合并聚类算法(上篇)
    UVaLive 7371 Triangle (水题,判矩形)
    UVaLive 7372 Excellence (水题,贪心)
    POJ 3312 Mahershalalhashbaz, Nebuchadnezzar, and Billy Bob Benjamin Go to the Regionals (水题,贪心)
    UVa 1252 Twenty Questions (状压DP+记忆化搜索)
    UVa 10817 Headmaster's Headache (状压DP+记忆化搜索)
  • 原文地址:https://www.cnblogs.com/xuesu/p/4328923.html
Copyright © 2011-2022 走看看