poj1039--Pipe(计算几何)

poj1039:题目链接

题目大意:一条管子有n个折点,给出管子上壁n个点的坐标(x1,y1)(x2,y2)....,x1<x2<x3.....,其中管子粗是1,也就是说横截面的上面坐标(x,y),下面坐标(x,y-1)。问一束光从开始的点打入,最远照射到的位置,输出位置,或是全程

如果想让光照的最远,那么除了全程的可能外,光一定会与某一个管壁相交,并且会与管中的两个节点相交,否则就可以调整光的角度,使其照的更远,枚举这两个点的位置,然后逐个点处判断相交的位置。

#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
using namespace std ;
#define eqs 1e-9
/*
两直线相交,求焦点
ax + by + c = 0 ;
ux + vy + w = 0 ;
a/u != b/v 防止平行
交点:( (b*w-v*c)/(a*v-u*b) , (c*u-a*w)/(a*v-u*b) )
*/
struct point
{
    double x , y ;
} p[30];
int n ;
double a[4][4] = { {0,0,0,0},{0,-1,0,0},{0,0,0,-1},{0,-1,0,-1} } ;
double solve(point u,point v) {
    double a = (u.y-v.y)/(u.x-v.x) , b = u.y-a*u.x ;
    double x , y , ans = 0.0 ;
    int flag = 0 , i ;
    y = a*p[0].x + b ;
    if( y-p[0].y >= eqs || p[0].y-1.0-y >= eqs  ) return ans ;
    for(i = 1 ; i < n ; i++) {
        y = a*p[i].x + b ;
        if( y-p[i].y > eqs ) {
            flag = 1 ;
            break ;
        }
        else if( p[i].y-1.0-y > eqs ) {
            flag = 2 ;
            break ;
        }
        else
            ans += (p[i].x-p[i-1].x) ;
    }
    if( !flag ) return ans ;
    u = p[i-1] , v = p[i] ;
    if( flag == 2 ) u.y -= 1.0 , v.y -= 1.0 ;
    double k = (u.y-v.y)/(u.x-v.x) , c = u.y-k*u.x ;
    x = (b-c)/(k-a) ;
    ans += (x-p[i-1].x) ;
    return ans ;
}
int main()
{
    int  i , j , k ;
    double max1 , temp ;
    point u , v ;
    while( scanf("%d", &n) && n )
    {
        max1 = 0.0 ;
        for(i = 0 ; i < n ; i++)
            scanf("%lf %lf", &p[i].x, &p[i].y) ;
        for(i = 0 ; i < n ; i++)
            for(j = i+1 ; j < n ; j++)
                for(k = 0 ; k < 4 ; k++) {
                    u.x = p[i].x + a[k][0] ; u.y = p[i].y + a[k][1] ;
                    v.x = p[j].x + a[k][2] ; v.y = p[j].y + a[k][3] ;
                    temp = solve(u,v) ;
                    if( temp > max1 )
                        max1 = temp ;
                }
        if( fabs(p[n-1].x-p[0].x-max1) < eqs  )
            printf("Through all the pipe.\n") ;
        else
            printf("%.2lf\n", p[0].x+max1) ;
    }
    return 0 ;
}


你可能感兴趣的:(poj1039--Pipe(计算几何))