码迷,mamicode.com
首页 > 其他好文 > 详细

JZOJ 3517. 空间航行

时间:2019-08-21 21:26:02      阅读:75      评论:0      收藏:0      [点我收藏+]

标签:memset   return   包含   cst   clu   queue   des   空间   表示   

题目

Description

你是一艘战列巡洋舰的引擎操作人员,这艘船的船员在空间中侦测到了一些无法辨识的异常信号。你的指挥官给你下达了命令,让你制定航线,驾驶战列巡洋舰到达那里。

船上老旧的曲速引擎的速度是0.1AU/s。然而,在太空中分布着许多殖民星域,这些星域可以被看成一个球。在星域的内部,你可以在任何地方任意次跳跃到星域内部的任意一个点,不花费任何时间。

你希望算出到达终点的最短时间。
 

Input

输入包含多组测试数据。

对于每一组数据,第一行包含一个正整数n,表示殖民星域的数量。

接下来n 行,第i 行包含四个整数Xi,Yi,Zi,Ri,表示第i个星域的中心坐标为(Xi, Yi,Zi),星域的半径是Ri。

接下来两行,第一行包含值Xa,Ya,Za,告诉你当前坐标为(Xa, Ya,Za)。

第二行包含值Xo,Yo,Zo,告诉你目的地坐标为(Xo, Yo,Zo)。

输入以一行单独的-1 结尾。所有坐标的单位都是天文单位(AU)。

Output

对于每一组输入数据,输出一行表示从目前的位置到达指定目的地的最短时间,取整到最近整数。输入保证取整是明确的。
 

Sample Input

1
20 20 20 1
0 0 0
0 0 10
1
5 0 0 4
0 0 0
10 0 0
-1

Sample Output

100
20
 

Data Constraint

每个输入文件至多包含10 个测试数据。

对于10% 的数据,n = 0。

对于30% 的数据,0<=n<=10。

对于100% 的数据,0<=n<=100,所有坐标的绝对值<=10000 ,半径r<=10000。

你可以认为,你所在的星区的大小为无限大。

 

分析

 

  • 首先我们考虑如何搞定一个三维的图
  • 将他搞成平面
  • 那我们就考虑如何跑最短路呢?
  • 星系之间的连边就是,原距离减去两个半径
  • 如果小于0
  • 那么距离就是0

 

代码

 1 #include<iostream>
 2 #include<queue>
 3 #include<cmath>
 4 #include<cstring>
 5 #include<cstdio>
 6 using namespace std;
 7 struct sb
 8 {
 9     double x,y,z,r;
10 }a[201];
11 double map[201][201];
12 int n;
13 double calc(int i,int j)
14 {
15     long long a1=(a[i].x-a[j].x)*(a[i].x-a[j].x);
16     long long b1=(a[i].y-a[j].y)*(a[i].y-a[j].y);
17     long long c1=(a[i].z-a[j].z)*(a[i].z-a[j].z);
18     long long sum=a1+b1+c1;
19     double k=sqrt(sum);
20     if (k-a[i].r-a[j].r>0) return k-a[i].r-a[j].r;
21     else return 0;
22 }
23 int vis[201];
24 double dis[201];
25 void spfa()
26 {
27     queue<int> q;
28     for (int i=0;i<=n+1;i++) dis[i]=1000000000.0000; 
29     memset(vis,0,sizeof(vis));
30     dis[0]=0; vis[0]=1; q.push(0);
31     while (!q.empty())
32     {
33         int x=q.front(); q.pop(); vis[x]=0;
34         for (int i=0;i<=n+1;i++)
35         {
36             if (map[x][i]>=0&&dis[i]>dis[x]+map[x][i])
37             {
38                 dis[i]=dis[x]+map[x][i];
39                 if (!vis[i])
40                 {
41                     q.push(i);
42                     vis[i]=1;
43                 } 
44             }
45         }
46     }
47 }
48 int main ()
49 {
50 //    freopen("warp.in","r",stdin);
51 //    freopen("warp.out","w",stdout);
52     cin>>n;
53     while (n!=-1)
54     {
55         memset(map,0,sizeof(map));
56         memset(a,0,sizeof(a));
57         for (int i=1,x,y,z,r;i<=n;i++)
58             cin>>a[i].x>>a[i].y>>a[i].z>>a[i].r;
59         cin>>a[0].x>>a[0].y>>a[0].z;
60         cin>>a[n+1].x>>a[n+1].y>>a[n+1].z;
61         for (int i=0;i<=n+1;i++)
62            for (int j=i;j<=n+1;j++)
63             {
64                 if (i==j) map[i][j]=-1;
65                 else 
66                 map[i][j]=map[j][i]=calc(i,j);
67             }
68         spfa();
69         cout<<round(dis[n+1]*10)<<endl;
70         cin>>n;
71     }
72 }

 

 

JZOJ 3517. 空间航行

标签:memset   return   包含   cst   clu   queue   des   空间   表示   

原文地址:https://www.cnblogs.com/zjzjzj/p/11391129.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!