zoukankan      html  css  js  c++  java
  • 线段相交+卡点——poj1039

    计算几何里常用的套路:两两枚举点卡住,然后看是不是满足条件

    poj上的题依然有很多坑,答案可能是负数,因为这个wa了好久

    /*
    枚举上端点i,下端点j,作为光线,那么max(i,j)以前的所有管道线段都不可以与该线相交
    同时求出max(i,j)以后的最近的交点在哪里(或没有) 
    */
    #include<iostream>
    #include<cstring>
    #include<cmath>
    #include<cstdio>
    using namespace std;
    #define N 205
    
    typedef double db;
    const db eps=1e-8;
    const db pi=acos(-1);
    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);}
    struct point{
        db x,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 cross(point k1,point k2){return k1.x*k2.y-k1.y*k2.x;}
    int intersect(db l1,db r1,db l2,db r2){
        if (l1>r1) swap(l1,r1); if (l2>r2) swap(l2,r2); return cmp(r1,l2)!=-1&&cmp(r2,l1)!=-1;
    }
    int checkSSS(point k1,point k2,point k3,point k4){//不严格相交 
        return sign(cross(k1-k3,k2-k3))*sign(cross(k1-k4,k2-k4))<=0;
    }
    int checkSS(point k1,point k2,point k3,point k4){//k1,k2:L  k3,k4:S
        return sign(cross(k1-k3,k2-k3))*sign(cross(k1-k4,k2-k4))<0;
    }
    int samedir(point k1,point k2,point k3,point k4){
        return sign(cross(k2-k1,k3-k1))*sign(cross(k2-k1,k4-k1))>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);
    }
    int n;
    point up[N],down[N],k1,k2,k3,k4;
    
    int main(){
        while(cin>>n && n){
            for(int i=1;i<=n;i++)    {
                cin>>up[i].x>>up[i].y;
                down[i]=up[i];
                down[i].y--;
            }
            
            double Max=-1e16;//这里一定要负无穷 
            int flag=0;
            for(int i=1;i<=n;i++)
                for(int j=1;j<=n;j++)if(i!=j){
                    int k;k1=up[i];k2=down[j];
                    for(k=1;k<n;k++){
                        if(checkSS(k1,k2,up[k],up[k+1]) || checkSS(k1,k2,down[k],down[k+1]))
                            break;    //和边相交 
                        if(!checkSSS(k1,k2,up[k],down[k]) || !checkSSS(k1,k2,up[k+1],down[k+1]))        
                           break;    //跑到外面 
                    }
                    if(k==n){flag=1;continue;}
                    if(k<max(i,j))continue;//这样的光线不合法 
                    //和段 k,k+1 相交了
                    if(checkSSS(k1,k2,up[k],up[k+1])){
                        k3=getLL(k1,k2,up[k],up[k+1]);
                        Max=max(Max,k3.x);
                    }  
                    if(checkSSS(k1,k2,down[k],down[k+1])){
                        k3=getLL(k1,k2,down[k],down[k+1]);
                        Max=max(Max,k3.x);
                    }
                }
            
            if(flag){
                puts("Through all the pipe.");
                continue;
            }
            else printf("%.2f
    ",Max);
        }
    } 
     
  • 相关阅读:
    第八章 多线程编程
    Linked List Cycle II
    Swap Nodes in Pairs
    Container With Most Water
    Best Time to Buy and Sell Stock III
    Best Time to Buy and Sell Stock II
    Linked List Cycle
    4Sum
    3Sum
    Integer to Roman
  • 原文地址:https://www.cnblogs.com/zsben991126/p/12329379.html
Copyright © 2011-2022 走看看