2018年中南大學機試題a題
題目描述
小王和小明是好朋友,兩人最開始各有一個初始位置 p 和一個恆定速度 v,從0時刻起開始,他們從初始位置以恆定速度開始行走,請告訴我行走過程中兩人的最短距離是多少。
輸入
一行輸入T代表測試樣例數目。
對於每個樣例,
第一行包含四個整數 x1,y1,x2,y2,表示人的起點(x1,y1),(x2,y2)。
第二行是四個整數u1,v1,u2,v2,表示人的初始速度(u1,v1),(u2,v2)(分別爲x軸和y軸方向的分速度)。
T <= 1000 , x1,y1,x2,y2,u1,v1,u2,v2的絕對值不大於1000。
輸出
對於每個樣例,輸出一行。“Case i: d”。i 代表案例編號,d代表答案,四捨五入到小數點後6位。
樣例輸入
5
1 1 2 2
1 1 2 2
1 1 2 2
1 1 -1 -1
1 1 2 2
0 1 0 -1
1 1 1 1
1 1 2 2
0 0 0 1
0 1 1 0
樣例輸出
Case 1: 1.414214
Case 2: 0.000000
Case 3: 1.000000
Case 4: 0.000000
Case 5: 0.707107
題目思路
這是道數學題,設t秒後兩個點的座標爲x3, y3,和x4,y4
x3 = x1 + t * u1 y3 = y1 + t * v1
x4 = x2 + t * u2 y4 = y2 + t * v2
距離的平方爲
(x4 - x3)^2 + (y4 - y3)^2
將上述x3, y3, x4, y4代入上式並化簡
[(u2-u1)^2 + (v2-v1)^2]* t^2 +2*t*[(u2-u1)*(x2-x1)+(y2-y1)*(v2-v1)]+(x2-x1)^2+(y2-y1)^2
這是個一元二次函數,a * t^2 + b * t + c
a = (u2-u1)^2 + (v2-v1)^2
b = 2 *[(u2-u1)*(x2-x1)+(y2-y1)*(v2-v1)]
c = (x2-x1)^2+(y2-y1)^2
- 第一種情況,起始兩個點的座標是相同的則最小距離就爲0
- 第二種情況,當u2=u1並且v2=v1.兩個點的x和y軸的移動速度都相同,則最小距離就是他們的起始距離
- 第三種情況,因爲是一元二次函數,並且2個點的距離都不可能小於0,所以開口肯定是向上的
- 當對稱軸小於0的時候,當t>=0的函數部分是遞增的,所以最小距離就是t=0的時候,即兩點起始距離
- 當對稱軸大於0的時候,最小距離就是當t取-b/2a的時候
上代碼
#include<stdio.h>
#include<math.h>
int main()
{
int v1, v2, u1, u2, x1, x2, y1, y2;
int V, X, Y, U, n;
double ans, t,a , b, c;
scanf("%d",&n);
for(int i = 1; i <= n; i++)
{
scanf("%d %d %d %d", &x1, &y1, &x2, &y2);
scanf("%d %d %d %d", &u1, &v1, &u2, &v2);
V = v2 - v1;
U = u2 - u1;
X = x2 - x1;
Y = y2 - y1;
a = U*U + V*V ;
b = 2 * (U*X + Y*V);
c = X*X + Y*Y;
if(x1 == x2 && y1 == y2)
{
ans = 0;
printf("Case %d: %.6lf\n", i, sqrt(ans));
continue;
}
if(a != 0)
{
t = (b*1.0)/(2*a);
t = -t;
if(t < 0) t = 0;
ans = a * t * t + b * t + c;
printf("Case %d: %.6lf\n", i, sqrt(ans));
}
else
{
ans = (x2-x1)*(x2-x1) + (y2-y1)*(y2-y1);
printf("Case %d: %.6lf\n", i, sqrt(ans));
}
}
return 0;
}