POJ 3304 Segments

题目大意:

给出n条线段两个端点的坐标,问所有线段投影到一条直线上,

如果这些所有投影至少相交于一点就输出Yes!,否则输出No!。

输入:

输入以t开头,显示测试用例的数量,然后,t测试用例跟随。每个测试案例以一行包含一个正整数n≤100显示段数。在那之后,N行包含四个实数x1 y1 x2 y2跟随,以(x1,y1),(x2,y2)是一个段的两个端点坐标。

输出:

对于每个测试用例,若存在您的程序必须输出“Yes!”,否则必须输出“No!”否则。你假设A和B两浮点数相等,当且| 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!
题解:计算几何
所有线段投影到一条线段都有公共点等价于存在一条垂线,与所有线段相交
判断相交可以用跨立实验,要注意浮点数误差
若存在一条这样的直线,可知存在一条符合条件的直线经过两个端点
还要考虑重点
 1 #include<iostream>
 2 #include<cstdio>
 3 #include<algorithm>
 4 #include<cstring>
 5 #include<cmath>
 6 using namespace std;
 7 struct Node
 8 {
 9     double x1,y1,x2,y2;
10 } line[10001];
11 double eps=1e-8;
12 int n;
13 double cross(double x1,double y1,double x2,double y2,int i)
14 {
15     double dx=x2-x1,dy=y2-y1;
16     double px=line[i].x1-x1,py=line[i].y1-y1;
17     double fx=line[i].x2-x1,fy=line[i].y2-y1;
18     return ((px*dy-py*dx)*(fx*dy-fy*dx));
19 }
20 bool judge(double x1,double y1,double x2,double y2)
21 {
22     int i;
23     if (sqrt((x2-x1)*(x2-x1)+(y2-y1)*(y2-y1))<eps) return 0;
24     for (i=1; i<=n; i++)
25     {
26         if (cross(x1,y1,x2,y2,i)>eps) return 0;
27     }
28     return 1;
29 }
30 bool exam(int i,int j)
31 {
32     if (judge(line[i].x1,line[i].y1,line[j].x1,line[j].y1)) return 1;
33     if (judge(line[i].x2,line[i].y2,line[j].x1,line[j].y1)) return 1;
34     if (judge(line[i].x2,line[i].y2,line[j].x2,line[j].y2)) return 1;
35     if (judge(line[i].x1,line[i].y1,line[j].x1,line[j].y1)) return 1;
36     return 0;
37 }
38 int main()
39 {
40     int T,i,ans,j;
41     cin>>T;
42     while (T--)
43     {
44         scanf("%d",&n);
45         for (i=1; i<=n; i++)
46         {
47             scanf("%lf%lf%lf%lf",&line[i].x1,&line[i].y1,&line[i].x2,&line[i].y2);
48         }
49         ans=0;
50         if (n==1)
51         {
52             cout<<"Yes!"<<endl;
53         }
54         else
55         {
56             for (i=1; i<n; i++)
57             {
58                 for (j=i+1; j<=n; j++)
59                     if (exam(i,j))
60                     {
61                         ans=1;
62                         break;
63                     }
64                 if (ans) break;
65             }
66             if (ans) cout<<"Yes!"<<endl;
67             else cout<<"No!"<<endl;
68         }
69     }
70 }

 

 
posted @ 2017-08-01 08:48  Z-Y-Y-S  阅读(229)  评论(0编辑  收藏  举报