POJ 3304(计算几何初步——判断线段和直线相交,加上枚举)

这题有2点要注意:

一丶当n==1时,应特判输出YES

二丶精度控制,当2点的距离相差小于1E-8,近似看作同一点。

View Code
 1 #include<iostream>
2 #include<cmath>
3 #define EPS 1e-8
4 #define MAXN 104
5 using namespace std;
6 struct point {
7 double x, y;
8 };
9 typedef point VECTOR;
10
11 struct segment {
12 point p[2];
13 }data[MAXN];
14
15 bool vis[MAXN];
16
17 double cross(point &p1, point &p2)
18 {
19 return p2.y*p1.x - p2.x*p1.y;
20 }
21
22 bool equal(point &sp, point &ep)
23 {
24 if (sqrt((sp.x - ep.x)*(sp.x - ep.x) + (sp.y - ep.y)*(sp.y - ep.y)) < EPS)return true;
25 return false;
26 }
27
28 bool check(point &sp, point &ep, int n)
29 {
30 for (int i(0); i<n; ++i) {
31 if (!vis[i]) {
32 VECTOR fir, sec, thr;
33 fir.x = data[i].p[0].x - sp.x;
34 fir.y = data[i].p[0].y - sp.y;
35 sec.x = ep.x - sp.x;
36 sec.y = ep.y - sp.y;
37 thr.x = data[i].p[1].x - sp.x;
38 thr.y = data[i].p[1].y - sp.y;
39 if (cross(fir, sec)*cross(sec, thr) < -EPS)return false;
40 }
41 }
42 return true;
43 }
44
45 bool judge(int n)
46 {
47 for (int i(0); i<n; ++i) {
48 vis[i] = true;
49 for (int num = 0; num<2; ++num) {
50 for (int j(i+1); j<n; ++j) {
51 for (int cnt = 0; cnt<2; ++cnt) {
52 if (!equal(data[i].p[num],data[j].p[cnt])) {
53 vis[j] = true;
54 if (check(data[i].p[num],data[j].p[cnt],n))return true;
55 vis[j] = false;
56 }
57 }
58 }
59 }
60 vis[i] = false;
61 }
62 return false;
63 }
64
65 int main()
66 {
67 int T;
68 scanf("%d",&T);
69 while (T--) {
70 memset(vis,false,sizeof(vis));
71 int n;
72 scanf("%d",&n);
73 for (int i(0); i<n; ++i) {
74 scanf("%lf%lf%lf%lf",&data[i].p[0].x,&data[i].p[0].y,&data[i].p[1].x,&data[i].p[1].y);
75 }
76 if (n == 1) {
77 cout<<"Yes!\n";
78 continue;
79 }
80 if (judge(n)) {
81 cout<<"Yes!\n";
82 } else {
83 cout<<"No!\n";
84 }
85 }
86 return 0;
87 }



你可能感兴趣的:(poj)