题目链接
题目大意
给出一个底部圆圆心为(0,0,0),半径为r,高为h的圆锥,问起始位置为 ,方向为 的点撞上圆锥的时间。
题目思路
想了一段时间都没什么思路,其实就是很普通的一个解方程。。。
假设碰撞点的坐标为(x,y,z)那么根据相似三角形
然后根据
可以推导出
然后不就是解一个二元一次方程吗
要注意的是,我们写出的圆锥方程是 的,而在程序中没有表示所以是上下两个圆锥底对底拼在一起的,因此我们得到两个撞击点。因为保证了撞击点是存在的,所以我们只需要判断, 时的撞击点是否满足 且
代码
#include<set>
#include<map>
#include<queue>
#include<stack>
#include<cmath>
#include<cstdio>
#include<vector>
#include<string>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<unordered_map>
#define fi first
#define se second
#define debug printf(" I am here\n");
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int,int> pii;
const ll INF=0x3f3f3f3f3f3f3f3f;
const int maxn=1e5+5,inf=0x3f3f3f3f,mod=1e9+7;
const double eps=1e-10;
int tot;
double r,h,x0,y0,z0,vx,vy,vz;
signed main(){
int _;scanf("%d",&_);
while(_--){
scanf("%lf%lf",&r,&h);
scanf("%lf%lf%lf",&x0,&y0,&z0);
scanf("%lf%lf%lf",&vx,&vy,&vz);
double a=vx*vx*h*h+vy*vy*h*h-r*r*vz*vz;
double b=2*x0*vx*h*h+2*y0*vy*h*h+2*h*vz*r*r-2*z0*vz*r*r;
double c=x0*x0*h*h+y0*y0*h*h-r*r*h*h-r*r*z0*z0+2*h*z0*r*r;
double t1=(-b-sqrt(b*b-4*a*c))/(2*a);
double t2=(-b+sqrt(b*b-4*a*c))/(2*a);
if(t1>t2) swap(t1,t2);
if(t1<0){
printf("Case %d: %.10f\n",++tot,t2);
}else{
if(0<=z0+vz*t1&&z0+vz*t1<=h){
printf("Case %d: %.10f\n",++tot,t1);
}else{
printf("Case %d: %.10f\n",++tot,t2);
}
}
}
return 0;
}