南邮 OJ 1041 线段相交



线段相交

时间限制(普通/Java) :  1000 MS/ 3000 MS          运行内存限制 : 65536 KByte
总提交 : 476            测试通过 : 106 

比赛描述

你将判断给定线段L1L2是否相交其中L1表示为s1x,s1y,e1x,e1yL2表示为s2x,s2y,e2x,e2y



输入

多组数据输入,每组一行,每组八个浮点数,s1x,s1y,e1x,e1y,s2x,s2y,e2x,e2y

输出

相交则输出yes否则输出no

样例输入

0 1 2 1 1 0 1 2
1 1 2 2 3 3 4 4

样例输出

yes
no

题目来源

NUAA




#include <iostream>
using namespace std;
bool crossed(double &x1,double &y1,double &x2,double &y2,
			 double &x3,double &y3,double &x4,double &y4){
	double X, Y;									//两直线的交点
	if(x1==x2 && x3==x4){							//L1、L2都垂直于x轴
		return 0;
	}else if(x1==x2){								//仅仅L1垂直于x轴
		Y = y3+(y4-y3)/(x4-x3)*(x1-x3);				//两直线交点纵坐标
		if( (x3-x1)*(x4-x1)<=0 && (Y-y1)*(Y-y2)<=0 ){
			return 1;
		}else{
			return 0;
		}
	}else if(x3==x4){								//仅仅L2垂直于x轴
		Y = y1+(y2-y1)/(x2-x1)*(x3-x1);				//两直线交点纵坐标
		if( (x1-x3)*(x2-x3)<=0 && (Y-y3)*(Y-y4)<=0 ){
			return 1;
		}else{
			return 0;
		}		
	}else{											//L1、L2都不垂直与x轴
		//L1: y = ax + b 
		//L2: y = mx + n 
		double a, b, m, n;
		a = (y1 - y2) / (x1 - x2);
		b = y1 - a * x1;
		m = (y3 - y4) / (x3 - x4);
		n = y3 - m * x3;
		if(a == m)									//两直线平行
			return false;
		X = (n-b)/(a-m);
		Y = a * X + b;
		if( (X-x1)*(X-x2)<=0 &&(Y-y1)*(Y-y2)<=0 && (X-x3)*(X-x4)<=0 && (Y-y3)*(Y-y4)<=0 )
			return 1;
		else
			return 0;		
	}
}
int main(){
	double x1,y1,x2,y2,x3,y3,x4,y4;
	while(cin>>x1>>y1>>x2>>y2>>x3>>y3>>x4>>y4){
		if(crossed(x1,y1,x2,y2,x3,y3,x4,y4))
			cout<<"yes"<<endl;
		else
			cout<<"no"<<endl;
	}
}


你可能感兴趣的:(ACM,线段相交,南邮OJ)