Segments(poj3304,判斷線段與直線相交)

http://poj.org/problem?id=3304

Segments

Time Limit: 1000MS Memory Limit: 65536K

Total Submissions: 8270 Accepted: 2507

Description

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

Input

Input begins with a number T showing the number of test cases and then, T test cases follow. Each test case begins 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 (x1, y1) and (x2, y2) are the coordinates of the two endpoints for one of the segments.

Output

For each test case, your program must output "Yes!", if a 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!

Source

Amirkabir University of Technology Local Contest 2006

解析:

題意:給出n條線段,判斷是否存在這樣的一條直線,所有線段的投影在其上,且至少有一個交點

思路:判斷直線與線段是否相交:

轉化成是否有一直線與所有的線段相交

暴力枚舉每兩條線段端點形成直線,判斷該直線是否與所有線段都相交

注意特殊情況的處理

1.n==1,時這樣的直線一定可以

2.枚舉端點時注意端點不重合,因爲兩點才能確定一條直線

192K 32MS C++ 2002B

*/

#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<math.h>
#include<algorithm>
using namespace std;
const int maxn=100+10;
const double eps=1e-9;
int n;
struct point
{
double x,y;
point(double x=0,double y=0):x(x),y(y){ }
}p[maxn][2];
point operator+(point A,point B)
{return point(A.x+B.x,A.y+B.y);}
point operator-(point A,point B)
{return point(A.x-B.x,A.y-B.y);}
point operator/(point A,double p)
{return point(A.x/p,A.y/p);}
point operator*(point A,double p)
{return point(A.x*p,A.y*p);}
bool operator<(const point& A,const point& B)
{return A.x<B.x||(A.x==B.x&&A.y<B.y);}
bool operator==(const point& A,const point& B)
{return A.x==B.x&&A.y==B.y;}
int dcmp(double x)
{
if(fabs(x)<eps)
return 0;
else
return x<0? -1:1;
}
double dis(point A,point B)
{
return sqrt((A.x-B.x)*(A.x-B.x)+(A.y-B.y)*(A.y-B.y));
}
double Cross(point A,point B)
{
return A.x*B.y-A.y*B.x;
}
bool isIntersect(point p1,point p2,point Q1,point Q2)
{
//printf("CROSS=%.0lf\n",Cross(p1-Q1,Q2-Q1)*Cross(Q2-Q1,p2-Q1));
 if(Cross(p1-Q1,Q2-Q1)*Cross(Q2-Q1,p2-Q1)>=0)
 return 1;
 else
 return 0;
}
bool check(point Q1,point Q2)
{
if(dcmp(dis(Q1,Q2))==0)return false;//如果只有一個點是不能構成一條直線
for(int i=0;i<n;i++)
{
if(isIntersect(p[i][0],p[i][1],Q1,Q2)==0)
{
return false;
}
}
return true;
}
int main()
{
    int i,j,T;
    scanf("%d",&T);
    while(T--)
    {
    	scanf("%d",&n);
    	for(i=0;i<n;i++)
    	{
    	 scanf("%lf%lf%lf%lf",&p[i][0].x,&p[i][0].y,&p[i][1].x,&p[i][1].y);
    	}
    	int ok=0;
    	if(n==1)
    	ok=1;
    	for(i=0;i<n;i++)
    	{  if(ok)
    	    break;
    	 for(j=0;j<n;j++)
    	 {
    	 if(check(p[i][0],p[j][0])||check(p[i][1],p[j][0])||check(p[i][0],p[j][1])||check(p[i][1],p[j][1]))
    	 {
    	 ok=1;
    	 //printf("ok==%d\n",ok);
    	 break;
    	 }
    	 }
    	}
    	if(ok)
    	printf("Yes!\n");
    	else
    	printf("No!\n");
    }
    return 0;
}


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