pku 1039 Pipe 叉积的应用

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

黑书上的一道题目:

题意:有一宽度为1的折线管道,上面顶点为(xi,yi),所对应的下面顶点为(xi,yi-1),假设管道都是不透明的,不反射的,光线从左边入口处的(x0,y0),(x,y0-1)之间射入,向四面八方传播,求解光线最远能传播到哪里(取x坐标)或者是否能穿透整个管道.
     如果一根光线自始至终都未擦到任何顶点,那么它肯定不是最优的,因为可以通过平移来使之优化,如果只碰到一个顶点,那也不是最优的,可以通过旋转,使它碰到另一个顶点,并且更优,即最优光线一定擦到一个上顶点和一个下顶点.
  这样枚举所有的上下两个转折点形成线段,然后从0到n枚举所有转折点如果与之相交则满足,直到找到不想交的然后计算x,找出最大的x即可。

#include <cstdio>
#include <cstring>
#include <iostream>
#define maxn 21
using namespace std;
const double eps = 1e-8;
struct point
{
    double x,y;
}up[maxn],down[maxn];
int n;
int dblcmp(double x)
{
    if (x > eps) return 1;
    else if (x < -eps) return -1;
    else return 0;
}
double det(double x1,double y1,double x2,double y2)
{
    return x1*y2 - x2*y1;
}
double cross(point a,point b,point c)
{
    return det(b.x - a.x,b.y - a.y,c.x - a.x,c.y - a.y);
}
double getx(point a,point b,point c,point d)
{
    double k1,k2,b1,b2;
    k1 = (b.y - a.y)/(b.x - a.x);
    k2 = (d.y - c.y)/(d.x - c.x);
    b1 = a.y - k1*a.x;
    b2 = d.y - k2*d.x;
    return (b2 - b1)/(k1 - k2);
}
void solve()
{
    int i,j,k;
    double ans = -10000000.0;
    for (i = 0; i < n; ++i)
    {
        for (j = 0; j < n; ++j)
        {
            if (i == j) continue;//同一个转折点上下就不用了
            //寻找不想交的
            for (k = 0; k < n; ++k)
            {
                if (dblcmp(cross(up[i],down[j],up[k]))*dblcmp(cross(up[i],down[j],down[k])) > 0)
                break;
            }
            double temp = 0;
            //计算x,并求出最大
            if (k < max(i,j)) continue;
            temp = getx(up[i],down[j],up[k],up[k - 1]);
            if (temp > ans) ans = temp;
            temp = getx(up[i],down[j],down[k],down[k - 1]);
            if (temp > ans) ans = temp;
            if (k >= n)
            {
                printf("Through all the pipe.\n");
                return ;
            }
        }
    }
    printf("%.2lf\n",ans);
}
int main()
{
    int i;
    while (~scanf("%d",&n))
    {
        if (!n) break;
        for (i = 0; i < n; ++i)
        {
            scanf("%lf%lf",&up[i].x,&up[i].y);
            down[i].x = up[i].x;
            down[i].y = up[i].y - 1.0;
        }
        solve();
    }
    return 0;
}

  

 

posted @ 2012-05-22 22:14  E_star  阅读(338)  评论(0编辑  收藏  举报