• 【经典】半平面交求解方程组——poj1755


    神坑,精度要调到1e-10,板子没问题

    /*
    二分距离,凸包所有边往左平移这个距离,半平面交后看是否还有核存在 
    */
    
    #include<iostream>
    #include<cstring>
    #include<cstdio>
    #include<cmath>
    #include<vector>
    #include<algorithm>
    #include<queue>
    using namespace std;
    #define N 205
    
    typedef double db;
    const db eps=1e-10;
    const db inf=1e10;
    const db pi=acos(-1.0);
    int sign(db k){
        if (k>eps) return 1; else if (k<-eps) return -1; return 0;
    }
    int cmp(db k1,db k2){return sign(k1-k2);}
    int inmid(db k1,db k2,db k3){return sign(k1-k3)*sign(k2-k3)<=0;}// k3 在 [k1,k2] 内 
    struct point{
        db x,y;
        point(){}
        point(db x,db y):x(x),y(y){}
        point operator + (const point &k1) const{return point(k1.x+x,k1.y+y);}
        point operator - (const point &k1) const{return point(x-k1.x,y-k1.y);}
        point operator * (db k1) const{return point(x*k1,y*k1);}
        point operator / (db k1) const{return point(x/k1,y/k1);}
        db abs(){return sqrt(x*x+y*y);}
        db abs2(){return x*x+y*y;}
        db dis(point k1){return ((*this)-k1).abs();}
        int getP() const{return sign(y)==1||(sign(y)==0&&sign(x)>=0);}
        point turn90(){return point(-y,x);}  
        point unit(){db w=abs(); return point(x/w,y/w);}
    };
    int inmid(point k1,point k2,point k3){return inmid(k1.x,k2.x,k3.x)&&inmid(k1.y,k2.y,k3.y);}
    db cross(point k1,point k2){return k1.x*k2.y-k1.y*k2.x;}
    db dot(point k1,point k2){return k1.x*k2.x+k1.y*k2.y;}
    int comp(point k1,point k2){
        if(k1.getP()==k2.getP())return sign(cross(k1,k2))>0;
        return k1.getP()<k2.getP();
    }
    
    struct line{
        point p[2];
        line(point k1,point k2){p[0]=k1; p[1]=k2;}
        point& operator [] (int k){return p[k];}
        int include(point k){return sign(cross(p[1]-p[0],k-p[0]))>0;}//k在l左端 
        point dir(){return p[1]-p[0];}
        line push(db eps){//向左边平移eps 
            point delta = (p[1]-p[0]).turn90().unit()*eps;
            return line(p[0]+delta,p[1]+delta); 
        }
    };
    
    //输入的点是顺时针:ans<0,逆时针:ans>0 
    bool judge(vector<point> v){
        double ans=0;
        for(int i=1;i<v.size()-1;i++)
            ans+=cross(v[i]-v[0],v[i+1]-v[0]);
        return ans>0;
    }
    point getLL(point k1,point k2,point k3,point k4){
        db w1=cross(k1-k3,k4-k3),w2=cross(k4-k3,k2-k3); return (k1*w2+k2*w1)/(w1+w2);
    }
    point getLL(line k1,line k2){return getLL(k1[0],k1[1],k2[0],k2[1]);}
    int parallel(line k1,line k2){return sign(cross(k1.dir(),k2.dir()))==0;}
    int sameDir(line k1,line k2){return parallel(k1,k2)&&sign(dot(k1.dir(),k2.dir()))==1;}
    int checkpos(line k1,line k2,line k3){
        point p=getLL(k1,k2);
        if(sign(cross(k3[1]-k3[0],p-k3[0]))>0)return 1;
        return 0;
    }//k1,k2交点在 k3 左端 
    int operator<(line k1,line k2){//按极角排序,角度相同的从左到右排 
        if(sameDir(k1,k2))return k2.include(k1[0]);
        return comp(k1.dir(),k2.dir());
    } 
    vector<line> getHL(vector<line> L,int flag){ // 求半平面交 , 半平面是逆时针方向 , 输出按照逆时针
        sort(L.begin(),L.end()); deque<line> q;
        /*
        if(flag){
            for(line l:L)cout<<l[0].x<<" "<<l[0].y<<" "<<l[1].x<<" "<<l[1].y<<'
    ';
        }*/
        
        for (int i=0;i<(int)L.size();i++){
            if (i&&sameDir(L[i],L[i-1])) continue;
            while (q.size()>1&&!checkpos(q[q.size()-2],q[q.size()-1],L[i])) q.pop_back();
            while (q.size()>1&&!checkpos(q[1],q[0],L[i])) q.pop_front();
            q.push_back(L[i]);
        }
        while (q.size()>2&&!checkpos(q[q.size()-2],q[q.size()-1],q[0])) q.pop_back();
        while (q.size()>2&&!checkpos(q[1],q[0],q[q.size()-1])) q.pop_front();
        vector<line>ans; for (int i=0;i<q.size();i++) ans.push_back(q[i]);
        return ans;
    }
    
    vector<point>v;
    vector<line>L;
    int n;
    db A[N],B[N],C[N];
    
    int solve(int id){
        L.clear();//加一个边框 
        L.push_back(line(point(0,0),point(inf,0)));
        L.push_back(line(point(inf,0),point(inf,inf)));
        L.push_back(line(point(inf,inf),point(0,inf)));
        L.push_back(line(point(0,inf),point(0,0)));
        for(int i=0;i<n;i++){        
            if(i==id)continue;
            //ax+by+c>0 的方程组通过半平面交求解 
            db a=1.0/A[i]-1.0/A[id];
            db b=1.0/B[i]-1.0/B[id];
            db c=1.0/C[i]-1.0/C[id];
            point k1,k2;    
            if(sign(a)==0){//by+c>0,
                if(sign(b)==0 && sign(c)<=0)return 0;
                else if(sign(b)==0 && sign(c)>0)continue;
                k1.x=0;k2.x=sign(b);
                k1.y=k2.y=-c/b;
            }
            else {
                if(sign(b)==0){//ax+c>0
                    k1.y=0,k2.y=-sign(a);
                    k1.x=k2.x=-c/a;
                }
                else {//ax+by+c>0
                    k1.x=0,k1.y=-c/b;
                    k2.x=sign(b),k2.y=-(c+a*sign(b))/b;
                }
            }
            L.push_back(line(k1,k2));
        } 
        /*
        if(id==2){
            for(line l:L)cout<<l[0].x<<" "<<l[0].y<<" "<<l[1].x<<" "<<l[1].y<<'
    ';
        }*/
        int flag=0;
        if(id==1)flag=1;
        vector<line>res=getHL(L,flag);//cout<<res.size()<<" ";
        /*for(auto l:res)
            cout<<l[0].x<<" "<<l[0].y<<" "<<l[1].x<<" "<<l[1].y<<'
    ';
        */if(res.size()>=3)return 1;
        return 0;
    }
    
    int main(){
        cin>>n;
        for(int i=0;i<n;i++)cin>>A[i]>>B[i]>>C[i];
        for(int i=0;i<n;i++)
            if(solve(i))puts("Yes");
            else puts("No");
    }
    
    /*
    13
    1020 1090 1080
    1000 1080 1100
    1000 1090 1100
    1010 1010 1090
    1090 1080 1010
    1060 1070 1040
    
    1080 1050 1020
    1040 1010 1060
    1090 1000 1010
    1070 1010 1030
    1060 1010 1040
    1070 1080 1030
    
    1040 1070 1060
    
    100
    1020 1090 1080
    1000 1080 1100
    1000 1090 1100
    1010 1010 1090
    1090 1080 1010
    1060 1070 1040
    
    1080 1050 1020
    1040 1010 1060
    1090 1000 1010
    1070 1010 1030
    1060 1010 1040
    
    1070 1080 1030
    1040 1070 1060
    1020 1000 1080
    1080 1070 1020
    1040 1000 1060
    1040 1060 1060
    1030 1080 1070
    1050 1020 1050
    1030 1010 1070
    1020 1060 1080
    1010 1060 1090
    1050 1030 1050
    1060 1040 1040
    1090 1030 1010
    1050 1080 1050
    1020 1050 1080
    1070 1050 1030
    1030 1050 1070
    1010 1020 1090
    1040 1050 1060
    1080 1080 1020
    1020 1020 1080
    1000 1050 1100
    1000 1020 1100
    1070 1030 1030
    1070 1040 1030
    1020 1070 1080
    1020 1080 1080
    1080 1090 1020
    1050 1070 1050
    1040 1040 1060
    1080 1040 1020
    1050 1040 1050
    1080 1020 1020
    1030 1040 1070
    1090 1040 1010
    1020 1030 1080
    1080 1060 1020
    1070 1020 1030
    1060 1030 1040
    1000 1040 1100
    1060 1080 1040
    1010 1040 1090
    1090 1090 1010
    1090 1060 1010
    1000 1060 1100
    1030 1090 1070
    1070 1060 1030
    1080 1000 1020
    1010 1000 1090
    1050 1060 1050
    1090 1070 1010
    1010 1030 1090
    1010 1080 1090
    1010 1050 1090
    1000 1070 1100
    1010 1070 1090
    1000 1010 1100
    1030 1030 1070
    1060 1090 1040
    1090 1050 1010
    1080 1010 1020
    1010 1090 1090
    1070 1090 1030
    1020 1010 1080
    1030 1020 1070
    1060 1050 1040
    1060 1060 1040
    1050 1050 1050
    1050 1090 1050
    1040 1090 1060
    1000 1030 1100
    1070 1070 1030
    1040 1020 1060
    1050 1000 1050
    1030 1070 1070
    1060 1000 1040
    1020 1040 1080
    1070 1000 1030
    1080 1030 1020
    1040 1030 1060
    1050 1010 1050
    1090 1020 1010
    1030 1060 1070
    1060 1020 1040
    1090 1010 1010
    1040 1080 1060
    1030 1000 1070
    1000 1000 1100
    
    */
  • 相关阅读:
    uva10912 Simple Minded Hashing(DP)
    uva10401 Injured Queen Problem(DP)
    uva702 The Vindictive Coach(DP)
    忍者X4将采取自动开通vip,论坛充值淘宝自助购买均可。步骤如下
    C盘不够大,可以这样操作
    任务思维1
    PHP 获取指定日期的星期方法如下
    学学C#开发client,server,C/S架构的程序
    今天的主角就是protobuf-net
    关于忍者站群X4-小飞镖服务器配置帮助汇总。
  • 原文地址:https://www.cnblogs.com/zsben991126/p/12378553.html
Copyright © 2020-2023  润新知