zoukankan      html  css  js  c++  java
  • 线段判交——poj2826

    目前poj似乎数据出了问题,拿以前a的代码交上去也是wa

    总体来说,要考虑三种答案0.00的情况

      1.线段不相交

      2.一根线段水平

      3.开口被封闭,即高的那一端把低的那一端完全遮住了

    #include<iostream>
    #include<cstring>
    #include<cstdio>
    #include<cmath>
    using namespace std;
    
    typedef double db;
    const db eps=1e-6;
    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(){}
        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};}
    };
    struct line{
        point p[2];
    };
    
    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 checkSS(point k1,point k2,point k3,point k4){
        return intersect(k1.x,k2.x,k3.x,k4.x)&&intersect(k1.y,k2.y,k3.y,k4.y)&&
        sign(cross(k3-k1,k4-k1))*sign(cross(k3-k2,k4-k2))<=0 &&
        sign(cross(k1-k3,k2-k3))*sign(cross(k1-k4,k2-k4))<=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 p[10],k1,k2,k3,k4,k5,k6,k7;
    line l1,l2,l3;
    
    int main(){
        int t;cin>>t;
        while(t--){
            scanf("%lf%lf",&k1.x,&k1.y);
            scanf("%lf%lf",&k2.x,&k2.y);
            scanf("%lf%lf",&k3.x,&k3.y);
            scanf("%lf%lf",&k4.x,&k4.y);
            l1.p[0]=k1;l1.p[1]=k2;
            l1.p[0]=k3;l1.p[1]=k4;
            if(checkSS(k1,k2,k3,k4)==0){
                puts("0.00");continue;
            }
            int tot=0;
            k5=getLL(k1,k2,k3,k4);//两线段交点 
            if(k1.y>k5.y)p[++tot]=k1;//找两个比交点高的点 
            if(k2.y>k5.y)p[++tot]=k2;
            if(k3.y>k5.y)p[++tot]=k3;
            if(k4.y>k5.y)p[++tot]=k4;
            if(tot!=2){
                puts("0.00");continue;
            }
            
            if(p[1].y>p[2].y)swap(p[1],p[2]);
            
            //判封闭,从p1用一根直线向上 
            point tmp=p[1];tmp.y+=100000;
                if(checkSS(p[1],tmp,k5,p[2])){
                point k8=getLL(p[1],tmp,k5,p[2]);
                if(k8.y>p[1].y){
                    puts("0.00");continue;
                } 
            }
            
            //求面积,从p1用一根直线横向延伸 
            k6=p[1];k6.x++;
            k7=getLL(k6,p[1],k5,p[2]);
            db area=0.5*(k6.y-k5.y)*fabs(k7.x-p[1].x);
            printf("%.2f
    ",area);
        }
    }
    /*
    9
    6259 2664 8292 9080 1244 2972 9097 9680
    0 1 1 0
    1 0 2 1
    0 1 2 1
    1 0 1 2
    0 0 10 10
    0 0 9 8
    0 0 10 10
    0 0 8 9
    0.9 3.1 4 0
    0 3 2 2
    0 0 0 2
    0 0 -3 2
    1 1 1 4
    0 0 2 3
    1 2 1 4
    0 0 2 3
    
    */
  • 相关阅读:
    C++——"%"运算符
    九度教程第22题——今年暑假不AC(看尽量多的电视节目)
    C++标准模板库 ——堆栈使用
    .Net转Java自学之路—基础巩固篇十三(集合)
    .Net转Java自学之路—基础巩固篇十二(多线程)
    .Net转Java自学之路—基础巩固篇十(异常)
    .Net转Java自学之路—基础巩固篇九(Object、内部类)
    .Net转Java自学之路—基础巩固篇八—总结(封装、继承、多态)
    .Net转Java自学之路—基础巩固篇七(接口、多态)
    .Net转Java自学之路—基础巩固篇六(继承)
  • 原文地址:https://www.cnblogs.com/zsben991126/p/12327687.html
Copyright © 2011-2022 走看看