CodeForces 44D-C - Hyperdrive-暴力

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


 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值