Hust oj 1559 线段相交(叉积)

线段相交
Time Limit: 1000 MSMemory Limit: 10240 K
Total Submit: 210(78 users)Total Accepted: 97(71 users)Rating: Special Judge: No
Description

给定线段P1P2(P1和P2是线段的两端点,且不重合)、P3P4(P3和P4是线段的两端点,且不重合),判断P1P2和P3P4是否相交。P1P2和P3P4相交,即指存在一个点P,它既落在P1P2上又落在P3P4上(含线段的端点)。

Input

输入数据有多组,第一行为测试数据的组数N,下面包括2N行,每组测试数据含2行,第一行为P1P2的坐标值,第二行为P3P4的坐标值,比如下面的数据

表示P1、P2、P3、P4的坐标分别为:P1(0,0),P2(1,1),P3(2,2),P4(3,3)


Output

判断每组数据中的线段P1P2和P3P4是否相交,如果相交输出YES,否则输出NO。每组数据输出占一行。

Sample Input
2
0 0 1 1
2 2 3 3
0 0 2 0
0 0 1 3
Sample Output
NO
YES
Hint

两线段相交分为“规范相交”和“非规范相交”。 “规范相交”指的是两条线段恰有唯一一个不是端点的公共点;而如果一条线段的一个端点在另一条线段上,或者两条线段部分重合,则视为“非规范相交”,本题是“非规范相交”。 

定义点坐标类型时需用double

 

就是判断两个线段是不是相交,先简单的筛一下,然后再用叉积判一下位置就好了。

#include <iostream>
using namespace std;
double min(double a,double b)
{
    return a<b?a:b;
}
double max(double a,double b)
{
    return a>b?a:b;
}
int main()
{
    int t;
    cin>>t;
    while(t--)
    {
        double x1,y1,x2,y2,x3,y3,x4,y4;
        long long int x,y,z,p;
        bool flag=0;
        cin>>x1>>y1>>x2>>y2>>x3>>y3>>x4>>y4;
        if (min(y1,y2)>max(y3,y4)||min(y3,y4)>max(y1,y2)||min(x3,x4)>max(x1,x2)||min(x1,x2)>max(x3,x4)) flag=1;
            if (flag==1) cout<<"NO"<<endl;
            else
            {
                x=(x2-x1)*(y3-y1)-(y2-y1)*(x3-x1);
                y=(x2-x1)*(y4-y1)-(y2-y1)*(x4-x1);
                z=(x4-x3)*(y1-y3)-(y4-y3)*(x1-x3);
                p=(x4-x3)*(y2-y3)-(y4-y3)*(x2-x3);
                if(x*y<=0&&z*p<=0) cout<<"YES"<<endl;
                else cout<<"NO"<<endl;
            }


    }
    return 0;
}


 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值