zoukankan      html  css  js  c++  java
  • poj 1039 Pipe(叉乘。。。)

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

    题意:有一宽度为1的折线管道,上面顶点为(xi,yi),所对应的下面顶点为(xi,yi-1),假设管道都是不透明的,不反射的,光线从左边入口处的(x1,y1),(x1,y1-1)之间射入,向四面八方传播,求解光线最远能传播到哪里(取x坐标)或者是否能穿透整个管道.

    思路:最优的是 光线过一个上顶点,一个下顶点。

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cstring>
     4 #include<iomanip>
     5 using namespace std;
     6 const double eps=1e-8;
     7 const int INF=1<<28;
     8 int n;
     9 
    10 struct point
    11 {
    12     double x,y;
    13 }up[100],down[100];
    14 
    15 int dblcmp(double x)
    16 {
    17     if(x<-eps) return -1;//一定要注意精度问题,不然样例都过不了
    18     if(x>eps) return 1;
    19     return 0; //在这里把接近0的数值都看成了0,实际这些数值就是0
    20 }
    21 
    22 double det(double x1,double y1,double x2,double y2)// 向量坐标点的叉乘
    23 {
    24     return x1*y2-x2*y1;
    25 }
    26 double cross(point a,point b,point c)//ab和ac向量的叉乘
    27 {
    28     return det(b.x-a.x,b.y-a.y,c.x-a.x,c.y-a.y);
    29 }
    30 
    31 double getx(point a,point b,point c,point d)//求ab和cd组成的直线交点的横坐标。
    32 {
    33     double b1,b2,k1,k2;
    34     k1=(b.y-a.y)/(b.x-a.x);
    35     k2=(d.y-c.y)/(d.x-c.x);
    36     b1=a.y-k1*a.x;
    37     b2=c.y-k2*c.x;
    38     return (b2-b1)/(k1-k2);
    39 }
    40 void solve()
    41 {
    42     int i,j,k;
    43     double ans=-INF,cnt;
    44     for(i=0; i<n; i++)
    45     {
    46         for(j=0; j<n; j++)
    47         {
    48             if(i==j) continue; //同一个横坐标的跳过
    49             for(k=0; k<n; k++)
    50             {
    51                 if(dblcmp(cross(up[i],down[j],up[k]))*dblcmp(cross(up[i],down[j],down[k]))>0)
    52                 break;//叉乘大于0说明 这条直线在两个点的同一侧,从叉乘的定义可以看出|a||b|sin&;
    53             }
    54             if(k<max(i,j)) continue; //如果这样的话 说明光线不存在。。。
    55             cnt=getx(up[i],down[j],up[k],up[k-1]);//找上顶点线的交点
    56             if(cnt>ans) ans=cnt;
    57             cnt=getx(up[i],down[j],down[k],down[k-1]);//找下顶点线的交点
    58             if(cnt>ans) ans=cnt;
    59             if(k==n)
    60             {
    61                 cout<<"Through all the pipe."<<endl;
    62                 return;
    63             }
    64         }
    65     }
    66     cout<<fixed<<setprecision(2)<<ans<<endl;
    67 }
    68 int main()
    69 {
    70     int i;
    71     while(~scanf("%d",&n)&&n)
    72     {
    73         for(i=0; i<n; i++)
    74         {
    75             cin>>up[i].x; cin>>up[i].y;
    76             down[i].x=up[i].x; down[i].y=up[i].y-1.0;
    77         }
    78         solve();
    79     }
    80     return 0;
    81 }
  • 相关阅读:
    十大佛教经典语,你最中意哪一句
    哲理人生名句, 拿个本子记下来
    逸乐有节 不可过度
    教你怎么用59秒就能打动客户?
    爱的意义
    一个聪明女人写的日记(转)
    做人做事十三条铁则
    爱上一个人的7个征兆
    办公室白领须知的18个定律
    生活智慧:奇特的人生法则
  • 原文地址:https://www.cnblogs.com/bfshm/p/3442248.html
Copyright © 2011-2022 走看看