題目連結 Pigs can’t take a sudden turn
Time limit:1000 ms Memory limit:65536 kB
Problem Descrpition
You maybe have ACed a question about computational geometry,which describes two dogs’ journey and calculate the shortest distance between them. Now, I provide a easier problem about two pigs. heir path are half-lines. When they start running, they won’t stop. Why? Because they can’t take a sudden turn.
So, I provide the start points of two pigs and their velocities. Please tell me the shortest distance between them.
We purpose that two pigs start running at the same time and will not stop because they are running in an vast grasslane without any tree.
If they smash into each other, the answer is zero and ignore the influence. Input
The first line is an integer T which indicates the number of cases. For each case, first line is four numbers x1,y1,x2,y2, indicate the start points of two pigs(x1,y1), (x2,y2). The second line is four numbers u1,v1,u2,v2, indicate the velocities of two pigs(u1,v1),(u2,v2). T <= 1000 The absolute value of x1,y1,x2,y2,u1,v1,u2,v2 will not lager than 1000. Output
For each case, you should output one line like ”Case i: d”. i stands for the case number and d stands for the answer, which should rounded to 6 decimal places. Sample Input
51 1 2 21 1 2 21 1 2 21 1 -1 -11 1 2 20 1 0 -11 1 1 11 1 2 20 0 0 10 1 1 0
Sample Output
Case 1: 1.414214Case 2: 0.000000Case 3: 1.000000Case 4: 0.000000Case 5: 0.707107
題意
在二維座標繫上,給出兩個點的起始位置和速度(向量表示),求兩點最近時的距離 解題思路
由已知條件推出兩點座標與時間的關係:A(x1+v1*t,y1+u1*t),B(x2+v2*t,y2+u2*t),再用距離公式得到一個距離跟時間的二次函數,然後就是二次函數求最小值的問題了,這裡開口必定向上,特判一下a=0也就是速度相等的情況就可以啦 Code
#include <cstdio>#include <iostream>#include <cmath>#define y1 YYusing namespace std;const double eps=1e-8;double a,b,c;double x1,y1,u1,v1;double x2,y2,u2,v2;double len(double t){ double ans=a*t*t+b*t+c; return sqrt(ans);}int main(){ int T,ca=1; scanf("%d",&T); while(T--) { scanf("%lf%lf%lf%lf",&x1,&y1,&x2,&y2); scanf("%lf%lf%lf%lf",&u1,&v1,&u2,&v2); c=(x1-x2)*(x1-x2)+(y1-y2)*(y1-y2); b=2*(x1-x2)*(u1-u2)+2*(y1-y2)*(v1-v2); a=(u1-u2)*(u1-u2)+(v1-v2)*(v1-v2); printf("Case %d: ",ca++); if(fabs(a)<eps) { printf("%.6f\n",len(0)); continue; } if(-b/(a*2)<0) { printf("%.6f\n",len(0)); } else { printf("%.6f\n",len(-b/(a*2))); } } return 0;}