51Nod-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示例
2
1 2 2 1 0 0 2 2
-1 1 1 1 0 0 1 -1
Output示例
Yes
No

51Nod 1264-线段相交


思路:分别判断 线段a是否与直线b相交,若都相交则 Yes ,否则No

线段a与直线b相交:求出线段a的中点及两个端点到直线b的距离 h0,h1,h2。若 h0*2==h1+h2则说明线段a在直线b的一侧,不相交;否则相交


code:


#include<iostream>
#include<cstdio>
#include<cmath>
using namespace std;

int T;
long long int l1[2][2];
long long int l2[2][2];

bool Cross(long long int l1[][2],long long int l2[][2]);
int main()
{
	ios::sync_with_stdio(false);
	cin.tie(0);
	cin>>T;
	while(T--){
		for(int i=0;i<2;++i)
			for(int j=0;j<2;++j)
				cin>>l1[i][j];
		for(int i=0;i<2;++i)
			for(int j=0;j<2;++j)
				cin>>l2[i][j];
		if(Cross(l1,l2)==true&&Cross(l2,l1)==true)	puts("Yes");
		else	puts("No");
	}
	
	return 0;
}

bool Cross(long long int l1[][2],long long int l2[][2])
{
	long long int h0,h1,h2;
	if(l1[0][0]==l1[1][0]){
		if(l2[0][0]<=l1[0][0]&&l2[1][0]>=l1[0][0]||
		l2[0][0]>=l1[0][0]&&l2[1][0]<=l1[0][0])
			return true;
		else	return false;
	}else{
		long long int a,b,c;
		a=l1[1][1]-l1[0][1];
		b=-(l1[1][0]-l1[0][0]);
		c=-b*l1[0][1]-a*l1[0][0];
		long long int x0=l2[0][0]+l2[1][0],y0=l2[0][1]+l2[1][1];
		h0=abs(a*x0+b*y0+c*2);
		h1=abs(a*l2[0][0]+b*l2[0][1]+c);
		h2=abs(a*l2[1][0]+b*l2[1][1]+c);
		long long int hh=h1+h2;
		if(!h1||!h2||h0!=hh)
			return true;	
		else	return false;
	}
}

另一思路是 用向量叉积来判断线段相交(暂时没看懂)

附上代码:


#include <stdio.h>

int CrossProduct(__int64 x1, __int64 y1, __int64 x2, __int64 y2)
{
    __int64 xx = x1 * y2;
    __int64 yy = y1 * x2;
    if (xx == yy) return 0;
    return xx > yy ? 1 : -1;
}

int main()
{
    int N;
    scanf("%d", &N);
    __int64 x1, y1, x2, y2, x3, y3, x4, y4;

    while (N--) {
        scanf("%I64d %I64d %I64d %I64d %I64d %I64d %I64d %I64d",
            &x1, &y1, &x2, &y2, &x3, &y3, &x4, &y4);
        
        if (CrossProduct(x2 - x1, y2 - y1, x3 - x1, y3 - y1) * CrossProduct(x2 - x1, y2 - y1, x4 - x1, y4 - y1) <= 0 &&
            CrossProduct(x4 - x3, y4 - y3, x1 - x3, y1 - y3) * CrossProduct(x4 - x3, y4 - y3, x2 - x3, y2 - y3) <= 0){
            printf("Yes\n");
        } else 	printf("No\n");
    }
    return 0;
}





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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值