WarCraft A-斯坦恩布莱德防御战

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;
}

猜你喜欢

转载自blog.csdn.net/zmc1248234377/article/details/79322418