标签:
Time Limit: 1000MS | Memory Limit: 10000K | |
Total Submissions: 9932 | Accepted: 3045 |
Description
Input
Output
Sample Input
4 0 1 2 2 4 1 6 4 6 0 1 2 -0.6 5 -4.45 7 -5.57 12 -10.8 17 -16.55 0
Sample Output
4.67 Through all the pipe.
Source
【思路】
线段直线相交。
如果一条直线没有经过两个拐点一定不是最优的直线,可以通过旋转移动使之更优。
枚举上线顶点,判断相交,求出交点。
【代码】
1 #include<cmath> 2 #include<cstdio> 3 #include<algorithm> 4 using namespace std; 5 const int N = 22; 6 const double eps = 1e-8; 7 8 struct Pt{ 9 double x, y; 10 }a[N], b[N]; 11 struct Line{ double a, b, c; }; 12 int n; 13 double ans; 14 15 double mult(Pt sp, Pt ep, Pt op){ 16 return (sp.x-op.x)*(ep.y-op.y) - (ep.x-op.x)*(sp.y-op.y); 17 } 18 Line getLine(Pt p1, Pt p2){ 19 Line ans; 20 ans.a = p1.y - p2.y; 21 ans.b = p2.x - p1.x; 22 ans.c = p1.x*p2.y - p2.x*p1.y; 23 return ans; 24 } 25 26 bool solve(Pt p1, Pt p2, int e){ 27 int i, flag; 28 for(i = 0; i < n-1; i ++) { 29 if(mult(p2, a[i], p1) < -eps || mult(p2, a[i+1], p1) < -eps){ 30 flag = 1; break; 31 } 32 if(mult(p2, b[i], p1) > eps || mult(p2, b[i+1], p1) > eps){ 33 flag = 2; break; 34 } 35 } 36 if(i == n-1) return true; // 没有与任何的管道相交,Through all the pipe. 37 if(i < e) return false; // 光线不合法。 38 Line l1, l2; // 光线合法,求出射到的最远距离。 39 l1 = getLine(p1, p2); 40 if(flag == 1) l2 = getLine(a[i], a[i+1]); 41 else l2 = getLine(b[i], b[i+1]); 42 ans = max(ans, (l1.b*l2.c-l2.b*l1.c)/(l1.a*l2.b-l2.a*l1.b)); 43 return false; 44 } 45 46 int main(){ 47 int i, j; 48 while(scanf("%d", &n) && n){ 49 for(i = 0; i < n; i ++){ 50 scanf("%lf%lf", &a[i].x, &a[i].y); 51 b[i].x = a[i].x; 52 b[i].y = a[i].y - 1; 53 } 54 ans = -1e9; 55 bool flag = 0; 56 if(n < 3) flag = 1; 57 for(i = 0; i < n; i ++) { 58 for(j = i + 1; j < n; j ++){ 59 flag = solve(a[i], b[j], j); 60 if(flag) break; 61 flag = solve(b[i], a[j], j); 62 if(flag) break; 63 } 64 if(flag) break; 65 } 66 if(flag) puts("Through all the pipe."); 67 else printf("%.2lf\n", ans); 68 } 69 return 0; 70 }
标签:
原文地址:http://www.cnblogs.com/lidaxin/p/5181134.html