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