poj3304求是否存在一条直线可以与各个线段有交点

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cmath>
#include <cstring>
#include <string.h>
#include <queue>         //poj3304求是否存在一条直线可以与各个线段有交点(枚举,枚举线段的端点和其他全部线段的端点来判断是否满足与所有线段相交)
#define N 105
using namespace std;
const double eps=1e-8;   //精度,相当于0
/*
若存在一条直线与所有线段相机相交,将该线旋转,平移,直到不能再动为止,此时该直线必定经过这些线段的某两个端点;
*/
struct segment 
{
	double x1, y1, x2, y2;
}p[N];
int n;
bool check(double x1, double y1, double x2, double y2)
{
	int t;
	double a1=x2-x1, b1=y2-y1, a2, b2, a3, b3;
	if(sqrt((x2-x1)*(x2-x1)+(y2-y1)*(y2-y1))<eps)  //两个点的距离小于1e-8就等价于一点
		return false;
	for(t=0; t<n; ++t)      //利用叉乘来判断直线和线段是否相交
	{
		a2=p[t].x1-x1;
		b2=p[t].y1-y1;
		a3=p[t].x2-x1;
		b3=p[t].y2-y1;
		if((a1*b2-b1*a2)*(a1*b3-b1*a3)>eps)break;  //精度控制,eps这里相当于0
	}
	if(t<n)return false;
	else return true;
}
		
int main()
{
	int t, j, T, ans;
	scanf("%d", &T);
	while(T--)
	{
		scanf("%d", &n);
		for(t=0; t<n; ++t)
		{
			scanf("%lf%lf%lf%lf", &p[t].x1, &p[t].y1, &p[t].x2, &p[t].y2);
		}
		if(n<3)
		{
			printf("Yes!\n");
			continue;
		}
		ans=0;
		for(j=0; j<n&&!ans; ++j)   //只要存在一条直线满足条件就立刻输出
		{
			for(t=0; t<n&&!ans; ++t)
			{
				if(t==j)continue;
				if(check(p[j].x1, p[j].y1, p[t].x2, p[t].y2)||check(p[j].x1, p[j].y1, p[t].x1, p[t].y1)||check(p[j].x2, p[j].y2, p[t].x1, p[t].y1)||check(p[j].x2, p[j].y2, p[t].x2, p[t].y2))
					ans=1;
			}
		}
		if(ans)
			printf("Yes!\n");
		else printf("No!\n");
	}
	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值