2018ccpc吉林 E:THE TOWER 解方程

The Tower shows atall tower perched on the top of a rocky mountain. Lightning strikes, setting the building alight, and two people leap frnm the windows, head first and arms outstretched. 
It is a scene of chaos and destruction.
There is a cone tower with base center at (0, 0, 0), base radius r and apex (0, 0, h) . At time 0 , a point located at ( x0 ,y0, z0) with velocity (vx,vy,vz). What time will they collide? Here is the cone tower.

 

输入

The first line contains testcase number T (T≤1000), For each testcase the first line contains spaceseparated real numbers rand h (1≤r,h≤1000) the base radius and the cone height correspondingly.
For each testcase the second line contains three real numbers x0 ,y0, z0 (0≤|x0|,|y0|,z0≤1000). For each testcase the third line contains three real numbers vx,vy,vx (). It is guaranteed that at time 0 the point is outside the cone and they will always collide.

输出

For each testcase print Case i: and then print the answer in one line, with absolute or relative error not exceeding 10-6

样例输入

2
1 2
1 1 1
-1.5 -1.5 -0.5
1 1
1 1 1
-1 -1 -1

样例输出

Case 1: 0.3855293381
Case 2: 0.5857864376

 

 

给你一个圆锥(位于坐标原点,告诉你高h 和底面半径 r),和一个点(x,y,z)并告诉你这个点的速度,

让你求点和圆锥相撞的最小时间(保证一定相撞)

 

 

点是个三维的坐标,还有初速度,那么首先想到要求一下圆锥的方程(画一个界面,然后设变量如图所示)

有三角形相似,易知r'=\frac{r*(h-z)}{h}

然后带入对于r'所在平面带入圆的方程得

x^{2}+y^{2}=r'^{2}=\frac{r^{2}*(h-z)^{2}}{h^{2}}\ (z\in [0,h])

这就是圆锥面的方程了(底面是x^{2}+y^{2}<=r^{2}\ \ (z=0)

 

然后我们设所用时间为t

易知撞击点为<x+t*v_{x},y+t*v_{y},z+t*v_{z}>

 

然后把它带入圆锥面方程,得到关于t的一元二次方程,求解即可

 

相撞点也可能是在底面上(易知z=0,由此解出t),所以

撞击点也可能是<x+\frac{-z}{v_{z}}*v_{x},y+\frac{-z}{v_{z}}*v_{y},0>,这个点不一定在x^{2}+y^{2}<=r^{2}\ \ (z=0)内,所以要判断下

 

 

 

你以为这样结束了吗,并没有,还有两个小坑点

这时候最近的点并不是答案,所以也要判断一下(也就是交点的z范围在0到h之间)

 

 

最后丢个代码

#include <bits/stdc++.h>
typedef long long ll;
using namespace std;
const int maxn = 1e5+7;
int T,Case;
int main(){
    for(scanf("%d",&T);T--;){
        double h,r;
        double x,y,z,vx,vy,vz;
        scanf("%lf%lf",&r,&h);
        scanf("%lf%lf%lf",&x,&y,&z);
        scanf("%lf%lf%lf",&vx,&vy,&vz);
        double  a = (vx*vx*h*h+vy*vy*h*h-r*r*vz*vz),
                b = 2*(x*vx*h*h+y*vy*h*h+vz*h*r*r-vz*z*r*r),
                c = h*h*x*x+h*h*y*y+2*h*r*r*z-r*r*z*z-r*r*h*h;
        double tans1 = (-b+sqrt(b*b-4*a*c))/(2*a);
        double tans2 = (-b-sqrt(b*b-4*a*c))/(2*a);
        double ans = 1e18;
        if(tans1>0){
            double tz = z+tans1*vz;
            if(tz>=0&&tz<=h)
                ans = min(ans,tans1);
        }
        if(tans2>0){
            double tz = z+tans2*vz;
            if(tz>=0&&tz<=h)
                ans = min(ans,tans2);
        }
        //printf("%f \n%f\n",tans1,tans2);
        if(fabs(vz)>1e-6){
            double t = -z/vz;
            double tx = x+t*vx,ty = y+t*vy;
            if(tx*tx+ty*ty<=r*r)
                ans = min(ans,t);
        }
        printf("Case %d: %.10f\n",++Case,ans);
    }
    return 0;
}

 

 

 

 

 

 

 

 

 

 

 

以后我解方程一定写好限定条件qwq

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值