题目 http://acm.hdu.edu.cn/showproblem.php?pid=4170
具体参见注释
/**
给你n个潜水艇的位置,和他矢量速度,然后给你直升飞机的初始位置,和他的标量速度,
直升飞机可以飞先任何方向,
现在要求直升飞机去给潜水艇送补给,(注意飞机在飞向潜水艇的过程中,潜水艇也会运动)
于是这就是一个二维追击问题.
于是先飞向哪个呢?我们发现n最多才为8,考虑全排列,最多2^8 = 256中可能全部暴力一遍得出最少的时间
那么对于其中的潜水艇怎么求这个二维追击问题.
设直升机的初始位置为 gx,gy,标量速度v;其中一个潜水艇的位置为 x,y 矢量速度:vx,vy;
有公式 (x-gx+vx*t)^2 + (y-gy+vy*t)^2 = (t*v)^2 ;画个图就能发现. 通过这个公式求出t;
(注意每到达一个潜艇,就要更新其他潜艇的位置.)
*/
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#define exp 1e-8
using namespace std;
const int INF = 0x3f3f3f3f;
typedef struct node
{
double x,y,vx,vy;
}point;
point submar[10],cove[10];
int p[10];
double hix,hiy,hiv;
double dis(double x,double y,double xx,double yy)
{
return sqrt((x-xx)*(x-xx)+(y-yy)*(y-yy));
}
void solve(int n,int caset)
{
double ans = INF;
do
{
double gx = hix,gy = hiy,gv = hiv;
for(int i=0;i<n;i++) cove[i] = submar[i];
double tempt = 0,tt = 0;
for(int i=0;i<n;i++)
{
if(!cove[p[i]].vx && !cove[p[i]].vy) ///防止除0错误(好像也不太需要)
{
tempt = dis(cove[p[i]].x,cove[p[i]].y,gx,gy) / gv;
}
else
{
double da = cove[p[i]].x - gx;
double db = cove[p[i]].y - gy;
double aa = cove[p[i]].vx*cove[p[i]].vx+cove[p[i]].vy*cove[p[i]].vy - gv*gv;
double bb = 2*(cove[p[i]].vx*da+cove[p[i]].vy*db);
double cc = da*da+db*db;
if(fabs(aa)<exp) tempt = -cc/bb;
else{
tempt = (-bb+sqrt(bb*bb-4*aa*cc))/(2*aa);
if(tempt<0) tempt = (-bb-sqrt(bb*bb-4*aa*cc))/(2*aa);
}
}
tempt += 1.0;
for(int j = i;j<n;j++)
{
cove[p[j]].x += cove[p[j]].vx*tempt;
cove[p[j]].y += cove[p[j]].vy*tempt;
}
gx = cove[p[i]].x;
gy = cove[p[i]].y;
tt+=tempt;
}
tt += dis(hix,hiy,gx,gy)/gv;
ans = min(ans,tt);
}while(next_permutation(p,p+n));
int h,m,s;
s = int(ans*3600+0.9999);///这个是防止误差.
m = s/60;
s %= 60;
h = m/60;
m %= 60;
printf("Case %d: %d hour(s) %d minute(s) %d second(s)\n",caset,h,m,s);
}
int main()
{
int n,caset = 1;
while(~scanf("%d",&n)&&n)
{
for(int i=0;i<n;i++)
{
scanf("%lf%lf%lf%lf",&submar[i].x,&submar[i].y,&submar[i].vx,&submar[i].vy);
}
scanf("%lf%lf%lf",&hix,&hiy,&hiv);
for(int i=0;i<n;i++) p[i] = i;
solve(n,caset++);
}
return 0;
}