http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=20073
题意:
给你n个星球的三维坐标, 从第一个星球出发,发射n-1个飞船
当第i个飞船到达第 i 个星球时,他会在上面造 n-2个 飞船,往其他星球发射, 同理 第j个到第j个星球也会造n-2个飞船做同样的事
当第i个星球造的飞船到达新的星球,他会造 n-3个飞船继续传播。。。。。
求任意两个飞船相撞的最短时间
飞船的路线都是直线。
由于题目说了不存在三点共面,那么 飞船是不可能交叉碰撞的, 例如 星1发往星3 的飞船 永远不会跟 星2 发往星3的飞船 碰撞, 因为如果发生了,必然存在 一个面使得星1 2 3 共面,不合要求;
那么碰撞的情况只有两种,一是两个飞船同时到达一个星球, 二是星1往星3发飞船,星3也往星1发飞船,他们在中间的过程碰撞;
【当第一个星球发射n-1个飞船到n-1个星球时,每个收到飞船的星球必然 往其他n-2个星球发飞船,也就是说 碰撞一定发生在这第二次发射中】
【那么我们可以转化为三角形模型】
可以看到 颜色相同的箭头表示 距离相等的一段路程, 显然 最终星2与星3 碰撞的 时间就是 【橙色+蓝色+黄色】 (本题距离就是速度.的...大小)
设星一到三的距离为 dis3 ,一到二的距离为dis2 二到三的距离为dis4
那么可知 对星1发射到 星2、3 到碰撞所需的时间为 【橙色+蓝色+黄色】 也即是
【橙色+蓝色 即 max(dis3,dis2)】+【黄色 即 [dis4- fabs(dis3-dis2)]/2】
所以暴力求出所有星球的距离,用公式求一个最小的答案就好了
#include <cstdio>
#include <cmath>
#include <cstring>
#include <string>
#include <algorithm>
#include <iostream>
#include <queue>
#include <map>
#include <set>
#include <vector>
using namespace std;
struct node
{
double a,b,c;
};
double max(double a,double b)
{return a<b?b:a;}
double min(double a,double b)
{return a>b?b:a;}
node tm[5005];
double one_2[5005];
const double inf= 2147483647.0;
int main()
{
double a,b,c;
int n;
int i,j;
scanf("%d",&n);
for (i=1;i<=n;i++)
{
scanf("%lf%lf%lf",&tm[i].a,&tm[i].b,&tm[i].c);
}
double a1=tm[1].a;
double b1=tm[1].b;
double c1=tm[1].c;
double dis_pow2;
for (j=2;j<=n;j++)
{
double a2=tm[j].a;
double b2=tm[j].b;
double c2=tm[j].c;
dis_pow2=sqrt((a1-a2)*(a1-a2)+(b1-b2)*(b1-b2)+(c1-c2)*(c1-c2));
one_2[j]=dis_pow2;
}
double ans=inf;
// sort(one_2+2,one_2+1+n,cmp);
int id;
double dis2;
for (id=2;id<=n;id++)
{
double dis1=one_2[id];
// int id=one_2[2].num;
a1=tm[id].a;
b1=tm[id].b;
c1=tm[id].c;
for (j=2;j<=n;j++)
{
if (j==id) continue;
double a2=tm[j].a;
double b2=tm[j].b;
double c2=tm[j].c;
dis2=sqrt((a1-a2)*(a1-a2)+(b1-b2)*(b1-b2)+(c1-c2)*(c1-c2));
double cha=fabs(dis1-one_2[j]);
ans=min(ans,dis1+(cha+dis2)/2);
}
}
printf("%.7lf\n",ans);
return 0;
}