题目链接:Problem - 7127 (hdu.edu.cn)
题目中文翻译:
计算几何和计算机图形学是计算机科学中非常难的部分,Kanade无法管理它们。所以她不想再学CG了。她去打篮球了。
篮球比赛中唯一重要的装备是球和篮筐——一个带篮筐的扁平长方形篮板。我们用侧视图来描述环箍。忽略厚度,篮板被视为平行于y轴的一段,篮筐被视为平行于x轴的一段。篮筐的右端与篮板相连。
为了简化模型,我们认为篮球是一个质量点。仅考虑重力,如果我们忽略篮筐和篮板,篮球的轨迹将是一条抛物线y=ax2+bx+c,a<0。但篮球很可能会击中篮板,从而改变运动轨迹。我们认为篮球和篮板(包括端点)之间的碰撞是完全弹性碰撞,这意味着篮球的X轴上的速度将被逆转,而Y轴上的速度将保持不变。在这个问题上,我们忽视了法庭。
如果篮球从上到下通过篮筐(不包括端点),我们认为射门是一个目标。一旦篮球触及篮框的任意一个端点,这意味着它击中了篮框,篮球将被反弹而无法进球。此外,根据规则,篮球不能从下到上穿过篮筐,或者是犯规,不能算作进球。
Kanade知道a、b、c的值以及篮板和篮筐的位置。
分析:先在图中给出数据的含义
y0就是篮球框的高度,y2是篮球挡板的最大高度,y1是地面的高度,x0和x1是篮球框边界.下面对有效进球进行逐步分析:
第一张图片显然是一个有效进球,第二张图片也是一个有效进球,只不过他是通过挡板反弹进的篮球框。容易发现第二张图片可以用下面这张图片代替:
经篮球挡板反弹后的篮球竖直速度并未改变,只是改变了球的水平速度,所以我们可以等价地看成穿过挡板后速度不变地继续进行,篮球挡板的后面有一个相同大小的篮球框,只要保证投进这两个篮球框内部就算进球。
容易知道:篮球框的两个边界是对称的,所以篮球框的有边界就是x1+(x1-x0),所以我们能不能等加成这样一个问题呢?只要保证球落在(x0,x1+(x1-x0)) 内就算进球了呢?
显然是不能的,举一个最简单的例子,当球的轨迹落在(x1,y0)的时候,根据题目的意思,显然这算是无效进球的,那还有没有什么特殊情况呢?比如说来看一下这张图片:
篮球直接飞出篮球挡板,但同样落在了(x0,x1+(x1-x0)),我们之前得到这个边界是因为假设篮球能够被篮球挡板反弹,但现在这种情况显然不符合题意,所以我们需要特判一下,现在我来总体梳理一下符合进球要求的篮球轨迹需要满足什么样的条件。
(1)球在x0处的高度不能小于等于y0(防止球从下面进入或者撞篮筐)
(2)球在x1处的高度不能高于y2,但题目中说篮球挡板的有效距离可以等于y2(防止篮球飞过挡板)
(3)球在(x1+(x1-x0))处的高度必须小于y0(保证根落在有效区间内)
(4)球在x1处的高度不能等于y0(等于y0被视为击中篮筐按作被弹出处理)
只要满足这4个条件,则说明一定是进球了,其他就没什么需要注意的了,下面是代码:
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
#include<queue>
using namespace std;
double a,b,c;
double cal(double x)
{
return a*x*x+b*x+c;
}
int main()
{
int T;
cin>>T;
double x0,x1,y0,y1,y2;
while(T--)
{
scanf("%lf%lf%lf",&a,&b,&c);
scanf("%lf%lf%lf%lf%lf",&x0,&x1,&y0,&y1,&y2);
if(cal(x0)<=y0||cal(x1)>y2||fabs(cal(x1)-y0)<0.0000001||cal(2*x1-x0)>=y0)
puts("No");
else
puts("Yes");
}
return 0;
}