WarCraft A-斯坦恩布莱德防御战
Description
由于洛丹伦南部的兽人暴动,不得不使人类联盟采取最后的手段进行镇压。国王泰瑞纳斯派出了两位最优秀的圣骑士以遏制兽人的不断骚扰。一位是白银之手的领袖:光明使者乌瑟尔,一位是他的儿子:阿尔萨斯王子。希望依靠他们的力量终结这次王国的危机。
阿尔萨斯的部队来到了位于奥特兰克山脉的斯坦恩布莱德,在这里他得知了一个不好的消息。村庄里的一名儿童小提米被残忍的豺狼人抓走了。为了自己的子民,阿尔萨斯决定带着自己的部队去营救小提米。
豺狼人带着小提米从(0,0)处开始沿着路径y=kx以速度v逃逸,阿尔萨斯的部队位于(a,b),那么为了使得追击距离最短并且能正好追上豺狼人,阿尔萨斯的部队应该采取怎样的速度呢?
Input
输入包括多行数据,每行数据有四个数k,a,b,v,输入以文件结尾结束。注意,0〈k,a,b,v〈1000。
Output
每行输出一个数,表示阿尔萨斯的部队的速度。如果不存在这样的速度,输出一行Impossible。输出的数保留三位小数。
Sample Input
1 1 1 1
2 2 2 2
Sample Output
0.000
0.667
该题实际上是一个求已知点到已知直线的距离的数学题。先求该点在直线上的垂点。
已知点(a,b)和直线y=kx。则(a,b)和垂点所在的直线方程为y-b=-1/k(x-a)。
联立两个直线的方程,即可求出垂点的坐标。接下来只需要再求出垂点到原点的距离d1以及点(a,b)到垂点的距离d2,用d1/v1=d2/v2,即可求出要求的速度v2。
代码如下:
#include <iostream>
#include <cmath>
using namespace std;
double node_X(double a,double b,double k)
{
if(k == 0.0)
return a;
return (b + a/k)/(k + 1.0/k);
}
double node_Y(double a,double b,double k,double x)
{
if(k == 0.0)
return 0.0;
return k*x;
}
//求平方
inline double square(double a)
{
return a*a;
}
//求两点之间的直线距离
double d(double x1,double y1,double x2,double y2)
{
return sqrt(square(x1 - x2)+square(y1 - y2));
}
int main()
{
double k,a,b,v;
double x,y,d1,d2;
while(cin >>k >> a >> b >> v)
{
if(b == -a/k)
{
cout << "Impossible" << endl;
continue;
}
x = node_X(a,b,k); //垂点的横坐标
y = node_Y(a,b,k,x); //垂点的纵坐标
d1 = d(x,y,0.0,0.0);
d2 = d(x,y,a,b);
printf("%0.3f\n",d2*v/d1);
}
return 0;
}