湖南大学ACM程序设计新生杯大赛(同步赛)C-Do you like Banana ? 【几何】

时间限制:C/C++ 1秒,其他语言2秒
空间限制:C/C++ 32768K,其他语言65536K
64bit IO Format: %lld
题目描述

Two endpoints of two line segments on a plane are given to determine whether the two segments are intersected (there is a common point or there is a partial coincidence that intersects). If intersected, output “Yes”, otherwise output “No”.
输入描述:
The first line is a number of T, indicating the number of tests inputed (1 <= T <= 1000)
For next T line,each line contains 8 numbers , x1,y1,x2,y2,x3,y3,x4, y4. (8-10 ^ < = xi, yi < = 10 ^ 8)
(the two endpoints of line 1 are x1, y1, |, x2, y2, and two of the endpoints of line 2 are x3, y3, |, x4, y4).
输出描述:
For each test case, output”Yes” if the two segments intersected, else output”No”.
示例1
输入

2
1 2 2 1 0 0 2 2
-1 1 1 1 0 0 1 -1
输出

Yes
No

问题:求两个线段能否相交。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
///----------alg 1------------
struct Point
{
    double x, y;
};

bool between(double a, double X0, double X1)
{
    double temp1 = a - X0;
    double temp2 = a - X1;
    if ((temp1<1e-8 && temp2>-1e-8) || (temp2<1e-6 && temp1>-1e-8))
    {
        return true;
    }
    else
    {
        return false;
    }
}


// 判断两条直线段是否有交点,有则计算交点的坐标
// p1,p2是直线一的端点坐标
// p3,p4是直线二的端点坐标
bool detectIntersect(Point p1, Point p2, Point p3, Point p4)
{
    double line_x, line_y; //交点
    if ((fabs(p1.x - p2.x)<1e-6) && (fabs(p3.x - p4.x)<1e-6))
    {
        return false;
    }
    else if ((fabs(p1.x - p2.x)<1e-6)) //如果直线段p1p2垂直与y轴
    {
        if (between(p1.x, p3.x, p4.x))
        {
            double k = (p4.y - p3.y) / (p4.x - p3.x);
            line_x = p1.x;
            line_y = k*(line_x - p3.x) + p3.y;

            if (between(line_y, p1.y, p2.y))
            {
                return true;
            }
            else
            {
                return false;
            }
        }
        else
        {
            return false;
        }
    }
    else if ((fabs(p3.x - p4.x)<1e-6)) //如果直线段p3p4垂直与y轴
    {
        if (between(p3.x, p1.x, p2.x))
        {
            double k = (p2.y - p1.y) / (p2.x - p1.x);
            line_x = p3.x;
            line_y = k*(line_x - p2.x) + p2.y;

            if (between(line_y, p3.y, p4.y))
            {
                return true;
            }
            else
            {
                return false;
            }
        }
        else
        {
            return false;
        }
    }
    else
    {
        double k1 = (p2.y - p1.y) / (p2.x - p1.x);
        double k2 = (p4.y - p3.y) / (p4.x - p3.x);

        if (fabs(k1 - k2)<1e-6)
        {
            return false;
        }
        else
        {
            line_x = ((p3.y - p1.y) - (k2*p3.x - k1*p1.x)) / (k1 - k2);
            line_y = k1*(line_x - p1.x) + p1.y;
        }

        if (between(line_x, p1.x, p2.x) && between(line_x, p3.x, p4.x))
        {
            return true;
        }
        else
        {
            return false;
        }
    }
}
///------------alg 1------------

int main()
{
    int T;
    scanf("%d", &T);
    while (T--) {
        double x1, x2, x3, x4;
        double y1, y2, y3, y4;
        scanf("%lf%lf%lf%lf%lf%lf%lf%lf", &x1, &y1, &x2, &y2, &x3, &y3, &x4, &y4);
        Point p1, p2, p3, p4;
        p1.x = x1, p1.y = y1;
        p2.x = x2, p2.y = y2;
        p3.x = x3, p3.y = y3;
        p4.x = x4, p4.y = y4;
        if (detectIntersect(p1, p2, p3, p4)) {
            printf("Yes\n");
        }
        else
        {
            printf("No\n");
        }
    }
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值