http://poj.org/problem?id=1039
题意:已知电缆是由一段段直的管道连接而成的,并知道这些管道的位置,问一束光从最左边射进来,你可以调节光入射的位置和角度,问最远能射到多远。(光束不能射穿管道)
枚举 : 一个最优的 直线 可能 和 管道没有交点,(但是 我们可以经过 平移,旋转 使其 与 管道 有 交点 这样的解 同样是最优 的,我们 枚举和 管道 有两个擦点的直线 (这样 才能 做这道题))
枚举上下两个顶点成光线所在直线,然后判断光线是否能合法,合法的话求出它射到的最远距离。
1 #include<cstdio>
2 #include<cstring>
3 #include<cmath>
4 #include<iostream>
5 #include<algorithm>
6 #include<set>
7 #include<map>
8 #include<queue>
9 #include<vector>
10 #include<string>
11 #define Min(a,b) a<b?a:b
12 #define Max(a,b) a>b?a:b
13 #define CL(a,num) memset(a,num,sizeof(a));
14 #define maxn 40
15 #define eps 1e-8
16 #define inf 100000000
17 #define mx 1<<60
18 #define ll __int64
19 using namespace std;
20
21 struct point
22 {
23 double x;
24 double y;
25 }up[maxn],dp[maxn];
26 double ans ;
27 int n ;
28 int dbcmp(double x)
29 {
30 if(fabs(x) < eps) return 0;
31 if(x< 0) return -1;
32 else return 1 ;
33
34 }
35 double det(double x1,double y1,double x2,double y2)
36 {
37 return x1*y2 - x2*y1 ;
38 }
39 double cross(point a,point b,point c)
40 {
41 return det(b.x - a.x,b.y - a.y,c.x - a.x,c.y - a.y);
42 }
43 double getx(point a,point b,point c,point d)// a,b 代表直线 ,c,d 代表 线段
44 {
45 double s1 = cross(a,b,c);
46 double s2 = cross(a,b,d);
47
48 return (c.x*s2 - d.x*s1)/(s2 - s1) ;// 求 交点 的 x 坐标
49 }
50 bool solve( )
51 {
52
53 int i, j,k;
54
55 for(i = 0 ; i< n;i++)
56 {
57 for(j = 0 ; j< n;j++)
58 {
59 if(i == j)continue ;
60 for(k = 0 ; k < n;k++)
61 {
62 if(dbcmp(cross(up[i],dp[j],up[k])) * dbcmp(cross(up[i],dp[j],dp[k])) >0)
63 break;
64 }
65
66 if(k == n)
67 {
68
69 return true;
70 }
71
72 if(k < max(i,j)) continue ;// 判断 是否合法
73 else
74 {
75 double tmp = getx(up[i],dp[j],up[k],up[k - 1]);
76 if(tmp > ans) ans = tmp;
77 tmp = getx(up[i],dp[j],dp[k],dp[k - 1]);
78 if(tmp >ans) ans = tmp ;
79 }
80
81 }
82 }
83
84
85
86 return false ;
87
88
89
90 }
91
92 int main()
93 {
94 int i,j;
95 //freopen("data.txt","r",stdin);
96 while(scanf("%d",&n),n)
97 {
98 for(i = 0 ; i < n;i++)
99 {
100 scanf("%lf%lf",&up[i].x,&up[i].y);
101 dp[i].x = up[i].x;
102 dp[i].y = up[i].y - 1;
103 }
104
105 ans = -inf;
106 bool flag = false ;
107 if(n < 3) flag = true ;
108 if(!flag)flag = solve();
109
110 if(flag) printf("Through all the pipe.\n");
111 else printf("%.2lf\n",ans) ;
112
113 }
114 }
2 #include<cstring>
3 #include<cmath>
4 #include<iostream>
5 #include<algorithm>
6 #include<set>
7 #include<map>
8 #include<queue>
9 #include<vector>
10 #include<string>
11 #define Min(a,b) a<b?a:b
12 #define Max(a,b) a>b?a:b
13 #define CL(a,num) memset(a,num,sizeof(a));
14 #define maxn 40
15 #define eps 1e-8
16 #define inf 100000000
17 #define mx 1<<60
18 #define ll __int64
19 using namespace std;
20
21 struct point
22 {
23 double x;
24 double y;
25 }up[maxn],dp[maxn];
26 double ans ;
27 int n ;
28 int dbcmp(double x)
29 {
30 if(fabs(x) < eps) return 0;
31 if(x< 0) return -1;
32 else return 1 ;
33
34 }
35 double det(double x1,double y1,double x2,double y2)
36 {
37 return x1*y2 - x2*y1 ;
38 }
39 double cross(point a,point b,point c)
40 {
41 return det(b.x - a.x,b.y - a.y,c.x - a.x,c.y - a.y);
42 }
43 double getx(point a,point b,point c,point d)// a,b 代表直线 ,c,d 代表 线段
44 {
45 double s1 = cross(a,b,c);
46 double s2 = cross(a,b,d);
47
48 return (c.x*s2 - d.x*s1)/(s2 - s1) ;// 求 交点 的 x 坐标
49 }
50 bool solve( )
51 {
52
53 int i, j,k;
54
55 for(i = 0 ; i< n;i++)
56 {
57 for(j = 0 ; j< n;j++)
58 {
59 if(i == j)continue ;
60 for(k = 0 ; k < n;k++)
61 {
62 if(dbcmp(cross(up[i],dp[j],up[k])) * dbcmp(cross(up[i],dp[j],dp[k])) >0)
63 break;
64 }
65
66 if(k == n)
67 {
68
69 return true;
70 }
71
72 if(k < max(i,j)) continue ;// 判断 是否合法
73 else
74 {
75 double tmp = getx(up[i],dp[j],up[k],up[k - 1]);
76 if(tmp > ans) ans = tmp;
77 tmp = getx(up[i],dp[j],dp[k],dp[k - 1]);
78 if(tmp >ans) ans = tmp ;
79 }
80
81 }
82 }
83
84
85
86 return false ;
87
88
89
90 }
91
92 int main()
93 {
94 int i,j;
95 //freopen("data.txt","r",stdin);
96 while(scanf("%d",&n),n)
97 {
98 for(i = 0 ; i < n;i++)
99 {
100 scanf("%lf%lf",&up[i].x,&up[i].y);
101 dp[i].x = up[i].x;
102 dp[i].y = up[i].y - 1;
103 }
104
105 ans = -inf;
106 bool flag = false ;
107 if(n < 3) flag = true ;
108 if(!flag)flag = solve();
109
110 if(flag) printf("Through all the pipe.\n");
111 else printf("%.2lf\n",ans) ;
112
113 }
114 }