线段判交——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\n",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

*/

原文地址:https://www.cnblogs.com/zsben991126/p/12327687.html

时间: 2024-08-02 21:53:29

线段判交——poj2826的相关文章

(线段判交的一些注意。。。)nyoj 1016-德莱联盟

1016-德莱联盟 内存限制:64MB 时间限制:1000ms 特判: No通过数:9 提交数:9 难度:1 题目描述: 欢迎来到德莱联盟.... 德莱文... 德莱文在逃跑,卡兹克在追.... 我们知道德莱文的起点和终点坐标,我们也知道卡兹克的起点和 终点坐标,问:卡兹克有可能和德莱文相遇吗?,并且保证他们走的都是直线. 输入描述: 几组数据,一个整数T表示T组数据 每组数据 8个实数,分别表示德莱文的起点和终点坐标,以及卡兹克的起点和终点坐标 输出描述: 如果可能 输出 Interseeti

(计算几何 线段判交) 51nod1264 线段相交

1264 线段相交 给出平面上两条线段的两个端点,判断这两条线段是否相交(有一个公共点或有部分重合认为相交). 如果相交,输出"Yes",否则输出"No". 输入 第1行:一个数T,表示输入的测试数量(1 <= T <= 1000) 第2 - T + 1行:每行8个数,x1,y1,x2,y2,x3,y3,x4,y4.(-10^8 <= xi, yi <= 10^8) (直线1的两个端点为x1,y1 | x2, y2,直线2的两个端点为x3,y

POJ1408-Fishnet(线段求交)

Fishnet Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 1788   Accepted: 1144 Description A fisherman named Etadokah awoke in a very small island. He could see calm, beautiful and blue sea around the island. The previous night he had enc

You can Solve a Geometry Problem too(线段求交)

http://acm.hdu.edu.cn/showproblem.php?pid=1086 You can Solve a Geometry Problem too Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 8861    Accepted Submission(s): 4317 Problem Description Many

线段判非严格相交+暴力——poj2653

O(n2)的暴力居然能过.. #include<iostream> #include<cstring> #include<cstdio> #include<cmath> using namespace std; #define N 200005 #define db double const db eps=1e-6; int sign(db k){if (k>eps) return 1; else if (k<-eps) return -1; r

判断线段相交 -- 51nod 1264 线段相交

http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1264 三角形的有向面积:a.x*b.y+b.x*c.y+c.x*a.y - a.x*c.y - c.x*b.y - b.x*a.y; 上面得到的即是以点A,B,C三点组成的三角形面积的两倍. 如果area >0 则点A,B,C呈逆时针排列. 如果area<0  则点A,B,C呈顺时针排列. 如果area=0  则点A,B,C三点共线. 那么判断线段1(两个端点poin

HDU 题目分类

基础题:1000.1001.1004.1005.1008.1012.1013.1014.1017.1019.1021.1028.1029.1032.1037.1040.1048.1056.1058.1061.1070.1076.1089.1090.1091.1092.1093.1094.1095.1096.1097.1098.1106.1108.1157.1163.1164.1170.1194.1196.1197.1201.1202.1205.1219.1234.1235.1236.1248.1

计算几何基础

记录点滴. 1 /* 2 2015.6 HT 3 ACM Work_8 4 5 */ 6 7 #include <iostream> 8 #include <cstdio> 9 using namespace std; 10 11 /* 12 线段判交--ACM 13 14 1.快速排斥实验 15 设以线段P1P2和线段Q1Q2为对角线的矩形为M,N;若M,N 不相交,则两个线段显然不相交: 16 2.跨立实验 17 如果两线段相交,则两线段必然相互跨立对方.若P1P2跨立Q1Q2

HDU分类

模拟题, 枚举 1002 1004 1013 1015 1017 1020 1022 1029 1031 1033 1034 1035 1036 1037 1039 1042 1047 1048 1049 1050 1057 1062 1063 1064 1070 1073 1075 1082 1083 1084 1088 1106 1107 1113 1117 1119 1128 1129 1144 1148 1157 1161 1170 1172 1177 1197 1200 1201 12