zoukankan      html  css  js  c++  java
  • The Tower(HDU6559+2018年吉林站+数学)

    题目链接

    传送门

    题意

    告诉你圆锥的底部圆的半径和圆锥的高,再给你一个点的坐标及其运动向量,问你这个点什么时候会与这个圆锥相撞。

    思路

    比赛场上二分一直没过但是有人二分过了,今天再写这题想再试下二分,最后发现了自己的问题所在(可能这个点在(check)的时候已经穿过圆锥但是我的代码会把它当成还没达到,所以就会使得(lb=mid))。最后按照公式求解过了。
    圆锥表面方程为

    [egin{aligned} egin{cases} frac{h-z}{h}=frac{R}{r}\ x^2+y^2= R end{cases} end{aligned} ]

    然后设相撞时间为(t),则点的坐标变成

    [x=x_0+v_xt\ y=y_0+v_yt\ z=z_0+v_zt ]

    然后联立化简得到

    [(v_x^2+v_y^2-frac{r^2v_z^2}{h^2})t^2+2(v_xx_0+v_yy_0-frac{z_0v_zr^2}{h^2}+frac{v_zr^2}{h})t+x_0^2+y_0^2-frac{r^2}{h^2}(h-z_0)^2=0 ]

    求得

    [t_1=frac{-b+sqrt{b^2-4ac}}{2a}\ t_2=frac{-b-sqrt{b^2-4ac}}{2a} ]

    最后再(check)是否恰好相撞取最小值即可。

    代码实现如下

    #include <set>
    #include <map>
    #include <deque>
    #include <queue>
    #include <stack>
    #include <cmath>
    #include <ctime>
    #include <bitset>
    #include <cstdio>
    #include <string>
    #include <vector>
    #include <cstdlib>
    #include <cstring>
    #include <iostream>
    #include <algorithm>
    #include <unordered_map>
    using namespace std;
    
    typedef long long LL;
    typedef pair<LL, LL> pLL;
    typedef pair<LL, int> pLi;
    typedef pair<int, LL> pil;;
    typedef pair<int, int> pii;
    typedef unsigned long long uLL;
    
    #define lson rt<<1
    #define rson rt<<1|1
    #define lowbit(x) x&(-x)
    #define name2str(name) (#name)
    #define bug printf("*********
    ")
    #define debug(x) cout<<#x"=["<<x<<"]" <<endl
    #define FIN freopen("D://Code//in.txt","r",stdin)
    #define IO ios::sync_with_stdio(false),cin.tie(0)
    
    const double eps = 1e-8;
    const int mod = 998244353;
    const int maxn = 5000 + 7;
    const double pi = acos(-1);
    const int inf = 0x3f3f3f3f;
    const LL INF = 0x3f3f3f3f3f3f3f3fLL;
    
    int t;
    double r, h, vx, vy, vz, x, y, z;
    
    bool check(double t) {
        double xx = x + vx * t;
        double yy = y + vy * t;
        double zz = z + vz * t;
        if(zz < 0) return false;
        if(zz > h) return false;
        double R = (h - zz) * r / h;
        return (sqrt(xx * xx + yy * yy) - R) <= eps;
    }
    
    int main() {
        scanf("%d", &t);
        int icase = 0;
        while(t--) {
            scanf("%lf%lf%lf%lf%lf%lf%lf%lf", &r, &h, &x, &y, &z, &vx, &vy, &vz);
            if(z < 0 && sqrt(x * x + y * y) <= r * r) {
                printf("Case %d: %.7f
    ", ++icase, abs(z) / abs(vz));
                continue;
            }
            double a = vx * vx + vy * vy  - r * r * vz * vz / h / h;
            double b = 2 * (vx * x + vy * y - z * vz * r * r / h / h + h * vz * r * r / h / h);
            double c = x * x + y * y - r * r / h / h * (h - z) * (h - z);
            double ans1 = (-b + sqrt(b * b - 4 * a * c)) / (2 * a);
            double ans2 = (-b - sqrt(b * b - 4 * a * c)) / (2 * a);
            double ans = INF;
            if(check(ans1)) ans = min(ans, ans1);
            if(check(ans2)) ans = min(ans, ans2);
            printf("Case %d: %.7f
    ", ++icase, ans);
        }
        return 0;
    }
    
  • 相关阅读:
    Java 8 Lambda 表达式
    OSGi 系列(十二)之 Http Service
    OSGi 系列(十三)之 Configuration Admin Service
    OSGi 系列(十四)之 Event Admin Service
    OSGi 系列(十六)之 JDBC Service
    OSGi 系列(十)之 Blueprint
    OSGi 系列(七)之服务的监听、跟踪、声明等
    OSGi 系列(六)之服务的使用
    OSGi 系列(三)之 bundle 事件监听
    OSGi 系列(三)之 bundle 详解
  • 原文地址:https://www.cnblogs.com/Dillonh/p/11196418.html
Copyright © 2011-2022 走看看