計算幾何--POJ--3304--Segments

Description

Given n segments in the two dimensional space,write a program, which determines if there exists a line such that afterprojecting these segments on it, all projected segments have at least one pointin common.

Input

Input begins with a number T showing the number of test cases andthen, T test cases follow. Each test casebegins with a line containing a positive integer n ≤ 100 showing the number of segments.After that, n lines containing four real numbers x1 y1 x2 y2 follow, in which (x1y1) and (x2y2) are thecoordinates of the two endpoints for one of the segments.

Output

For each test case, your program must output "Yes!", ifa line with desired property exists and must output "No!" otherwise.You must assume that two floating point numbers a and b are equal if |a - b|< 10-8.

Sample Input

3
2
1.0 2.0 3.0 4.0
4.0 5.0 6.0 7.0
3
0.0 0.0 0.0 1.0
0.0 1.0 0.0 2.0
1.0 1.0 2.0 1.0
3
0.0 0.0 0.0 1.0
0.0 2.0 0.0 3.0
1.0 1.0 2.0 1.0

Sample Output

Yes!
Yes!
No!

 

 題目大意:給你幾條直線,問你是否存在任意一條直線A(不是題目中給的直線),使得題目中給的直線在這條直線A上的投影至少存在一個交點,是就輸出YES,否則No。

這題要用到一個規律,如果多條直線投影到一條直線A上後有相交區域,那麼在相交區域內,作A的垂線,你會發現這條垂線和每條直線都相交,所以你要看是否存在A直線,只要判斷是否有一條直線B和題目中給的直線都相交就行了 

同時,相交區域的臨界情況就是一個點,而這個點肯定是某條直線的一個端點投影過來的,所以B這條直線你就可以遍歷題目中給的所有端點,然後看是否與每條直線相交。

#include<stdio.h>
#include<iostream>
#include<algorithm>
#include<string.h>
#include<math.h>
using namespace std;
const double eps=1e-8;
int n;
struct point{
	double x,y;
}p1[105],p2[105];		//p1存直線的一個端點,p2存另一個端點 
double mult(point p0,point p1,point p2)		//叉乘
{
	return (p1.x-p0.x)*(p2.y-p0.y)-(p2.x-p0.x)*(p1.y-p0.y);
}
bool judge(point pp1,point pp2)
{
	if(fabs(pp1.x-pp2.x)<eps&&fabs(pp1.y-pp2.y)<eps) 	//首先判斷是否是一個點 
        return false;
    for(int i=0;i<n;i++)
        if(mult(pp1,pp2,p1[i])*mult(pp1,pp2,p2[i])>eps) //判斷直線是否不相交 
		return false;
    return true;	//都不滿足就相交 
}
int main()
{
	int t,i,j;
	cin>>t;
	while(t--)
	{
		cin>>n;
		for(i=0;i<n;i++)
		cin>>p1[i].x>>p1[i].y>>p2[i].x>>p2[i].y;
		int flag=0;
		if(n<3)
		flag=1;
		else
		{
			for(i=0;i<n;i++)
			{
				for(j=i+1;j<n;j++)
				{
					if(judge(p1[i], p1[j])||judge(p1[i], p2[j])||judge(p2[i],p1[j])||judge(p2[i],p2[j]))	//枚舉端點構成的直線是否與題目中的直線相交 
                	flag=1;
                }
			}
		}
		if(flag) cout << "Yes!" << endl;
        else cout << "No!" << endl;
	}
} 



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章