zoukankan      html  css  js  c++  java
  • hdu6559 The Tower

    给出一个圆锥的半径,高,一个点的坐标和速度矢量,求最小的时间,使得点到达圆锥上

    解析几何就需要取设点

    圆心在原点的圆锥,半径为(r),高为(h)

    [left{egin{array}{l} frac{h-z}{h}=frac{R}{r} \ x^{2}+y^{2}=R^{2} end{array} ight. ]

    再设点的坐标

    [egin{array}{l} x=x_{0}+v_{x} t \ y=y_{0}+v_{y} t \ z=z_{0}+v_{z} t end{array} ]

    然后联立化简得到

    [left(v_{x}^{2}+v_{y}^{2}-frac{r^{2} v_{z}^{2}}{h^{2}} ight) t^{2}+2left(v_{x} x_{0}+v_{y} y_{0}-frac{z_{0} v_{z} r^{2}}{h^{2}}+frac{v_{z} r^{2}}{h} ight) t+x_{0}^{2}+y_{0}^{2}-frac{r^{2}}{h^{2}}left(h-z_{0} ight)^{2}=0 ]

    求得

    [egin{aligned} t_{1} &=frac{-b+sqrt{b^{2}-4 a c}}{2 a} \ t_{2} &=frac{-b-sqrt{b^{2}-4 a c}}{2 a} end{aligned} ]

    最后check一下,这样求出来是两个值,可能直接穿过圆锥面到另一个面,所以得判断一下才行。

    #include <iostream>
    #include <cstdio>
    #include <cmath>
    using namespace std;
    const double eps = 1e-6;
    double r, h, x0, y0, z0, vx, vy, vz;
    bool check(double tt){
        double x = x0 + vx * tt;
        double y = y0 + vy * tt;
        double z = z0 + vz * tt;
        double R = (h - z) * r / h;
        return (sqrt(x * x + y * y) - R) <= eps;
    }
    double min(double x, double y) {
        return x > y ? y : x;
    }
    void solve(int kase) {
        scanf("%lf%lf", &r, &h);
        scanf("%lf%lf%lf", &x0, &y0, &z0);
        scanf("%lf%lf%lf", &vx, &vy, &vz);
        printf("Case %d: ", kase);
        double a = vx * vx + vy * vy - r * r * vz * vz / h / h;
        double b = 2 * (vx * x0 + vy * y0 - z0 * vz * r * r / h / h + vz * r * r / h);
        double c = x0 * x0 + y0 * y0 - r * r / h / h * (h - z0) * (h - z0);
        double t1 = (-b + sqrt(b * b - 4 * a * c)) / (2 * a);
        double t2 = (-b - sqrt(b * b - 4 * a * c)) / (2 * a);
        double ans = 1000000000.0;
        if(check(t1)) {
            ans = min(ans, t1);
        }
        if(check(t2)) {
            ans = min(ans, t2);
        }
        printf("%.7f
    ", ans);
    }
    int main(){
       // freopen("in.txt", "r", stdin);
        //freopen("out.txt", "w", stdout);
        int t;
        scanf("%d", &t);
        for(int i = 1; i <= t; i++) solve(i);
        return 0;
    }
    
  • 相关阅读:
    使用火炬之光资源(转)
    (转)Visual Leak Detector (VLD)使用
    (转)ofusion 导出注意事项
    OgreMax 导出(转)
    (转)C++ 内存池 C++ Memory Pool 翻译版
    Maven教程初级篇01: 简介
    浅谈JSON 数据源格式
    面向连接的Socket Server的简单实现
    oracle杀死死锁进程
    重构——让程序员快乐的工作
  • 原文地址:https://www.cnblogs.com/Emcikem/p/13711312.html
Copyright © 2011-2022 走看看