1264 线段相交


基准时间限制:1 秒 空间限制:131072 KB 分值: 0  难度:基础题


 收藏

 关注

给出平面上两条线段的两个端点,判断这两条线段是否相交(有一个公共点或有部分重合认为相交)。 如果相交,输出"Yes",否则输出"No"。


Input


第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,y3 | x4, y4)


Output


输出共T行,如果相交输出"Yes",否则输出"No"。


Input示例

21 2 2 1 0 0 2 2-1 1 1 1 0 0 1 -1


Output示例


YesNo




李陶冶  (题目提供者)





#include<iostream>
#include<algorithm>
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<math.h>

#define eps 1e-8
#define zero(x) (((x) > 0 ? (x) : (-x)) < eps)

using namespace std;

struct point {
    double x,y;
};

struct line {
    point a,b;
};

double xmult(point p1,point p2,point p){
    return (p1.x - p.x)*(p2.y - p.y) - (p2.x - p.x)*(p1.y-p.y);
}

int dot_online_in(point p,line l){
    return zero(xmult(p,l.a,l.b)) && (l.a.x - p.x)*(l.b.x-p.x) < eps && (l.a.y - p.y)*(l.b.y - p.y) < eps;
}

int dot_inline(point p1,point p2,point p3){
    return zero(xmult(p1,p2,p3));
}

int same_side(point p1,point p2,line l){
    return xmult(l.a,p1,l.b)*xmult(l.a,p2,l.b)>eps;
}

int intersect_in(line u,line v){
    if(!dot_inline(u.a,u.b,v.a) || !dot_inline(u.a,u.b,v.b)){
        return !same_side(u.a,u.b,v) && !same_side(v.a,v.b,u);
    }
    return dot_online_in(u.a,v) || dot_online_in(u.b,v)
        || dot_online_in(v.a,u) || dot_online_in(v.b,u);
}

int main() {
    int T;
    scanf("%d",&T);
    while(T--) {
        line u,v;
        scanf("%lf%lf%lf%lf%lf%lf%lf%lf",&u.a.x,&u.a.y,&u.b.x,&u.b.y,&v.a.x,&v.a.y,&v.b.x,&v.b.y);
        int flag = intersect_in(u,v);
        if(flag == 1) {
            printf("Yes\n");
        } else {
            printf("No\n");
        }
    }
    return 0;
}