JZOJ 3517. 空间航行

Posted zjzjzj

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了JZOJ 3517. 空间航行相关的知识,希望对你有一定的参考价值。

题目

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. 空间航行的主要内容,如果未能解决你的问题,请参考以下文章

[并差集] Jzoj P5794 旅行

python 命名空间和作用域

python 基础---命名空间作用域

Python(56)_命名空间和作用域

python命名空间和作用域

Python命名空间和作用域