poj 1039 Pipe (判断 直线和 线段 是否相交 并 求交点)

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

题意:已知电缆是由一段段直的管道连接而成的,并知道这些管道的位置,问一束光从最左边射进来,你可以调节光入射的位置和角度,问最远能射到多远。(光束不能射穿管道)

 

poj <wbr>1039 <wbr>:Pipe <wbr>(几何)

题解:

枚举 :  一个最优的 直线  可能 和 管道没有交点,(但是 我们可以经过 平移,旋转 使其 与 管道 有 交点 这样的解 同样是最优 的,我们 枚举和 管道 有两个擦点的直线 (这样 才能 做这道题))

枚举上下两个顶点成光线所在直线,然后判断光线是否能合法,合法的话求出它射到的最远距离。

  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< 0return -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 }


原文地址:https://www.cnblogs.com/acSzz/p/2657539.html