poj 3304 Segments 线段与直线相交

本文介绍了一种算法,用于判断是否存在一条直线能够与给定的所有线段相交。通过枚举每一对线段并检查由它们组成的四条直线是否与其它线段相交来实现。
#include<cstdio>
#include<cstdlib>
#include<cmath>
const double eps = 1e-8;
int n;
struct Pt {
    double x, y;
    Pt() { }
    Pt(double x, double y) : x(x), y(y) { }
};
struct Sg {
    Pt s, t;
    Sg() { }
    Sg(Pt s, Pt t) : s(s), t(t) { }
    Sg(double a, double b, double c, double d) : s(a, b), t(c, d) { }
};
double norm(Pt p) { return sqrt(p.x*p.x + p.y*p.y); }
//double dist (Pt a, Pt b) { return (a-b).norm(); }
void print(Pt p) { printf("(%f, %f)", p.x, p.y); }
Sg seg[110];
double mult(Pt sp, Pt ep, Pt op){
    return (sp.x-op.x)*(ep.y-op.y) - (ep.x-op.x)*(sp.y-op.y);
}
bool fun(Pt p1,Pt p2){
	if(fabs(p1.x-p2.x)<eps&&fabs(p1.y-p2.y)<eps)
		return false;
	for(int i=0;i<n;++i){
		if(mult(p1,p2,seg[i].s)*mult(p1,p2,seg[i].t)>eps)
			return false;	
	}
	return true;	
}
int main(){
    int t;
    scanf("%d",&t);
    while(t--){
		scanf("%d",&n);
		for(int i=0;i<n;++i){
			scanf("%lf%lf%lf%lf",&seg[i].s.x,&seg[i].s.y,&seg[i].t.x,&seg[i].t.y);						
		}           
		bool flag=false;
		if(n<3) flag=true;
		for(int i=0;i<n&&!flag;++i){
			for(int j=i+1;j<n&&!flag;++j){
				if(fun(seg[i].s,seg[j].s)) flag=true;
				else if(fun(seg[i].s,seg[j].t)) flag=true;
				else if(fun(seg[i].t,seg[j].s)) flag=true;
				else if(fun(seg[i].t,seg[j].t)) flag=true;	
			}	
		}
		printf("%s\n",flag?"Yes!":"No!");
    }
    //system("pause");
    return 0;    
}

##总结

  1. 判断是否存在一条直线与所有线段相交,枚举任意两条线段,如果存在两条线段生成的四条直线与任意一条线段相交,则命题成立。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值