【最短路】Aircraft

  华夏60 超音速战斗机是当今世界上机动性能最先进的战斗机。战斗过程中的一个关键问题是如何在最短的时间内使飞机从当前的飞行高度和速度爬升/俯冲到指定的高度并达到指定速度,以便占据有利的战斗位置。

  现假定只允许华夏60 执行以下三种基本飞行动作,并且只能在完成了一个基本动作的情况下再去执行另一个基本飞行动作。这样华夏60 的飞行可以表示成由这三种基本飞行动作组成的动作序列。

  维持原速做恒速爬升飞行,直至飞行高度提高 ?h 英尺;

  水平加速飞直至速度提高1 马赫(1 马赫 ≈ 1200 公里/小时);

  垂直俯冲飞行 ?h 英尺,飞行速度会提高1 马赫。

  同时假定飞机的初始飞行速度和执行每个基本飞行动作初始时刻的飞行速度都是1 马赫的整数倍,且不超过6 马赫;初始飞行高度和执行每个基本飞行动作初始时刻的飞行高度都为 ?h 英尺( ?h 是整数)的整数倍。

  实验研究表明:在不同高度H 和不同的初始速度V 完成上述的三种基本飞行动作所需的时间也是各不相同的。表1~表3 给出了?h = 15000英尺和最大飞行高度Hm = 75000英尺时完成这三种基本飞行动作所需的时间。

表1 恒速爬升飞行


V

H


1


2


3


4


5


6


0


12


12


12


11


12


14


15000


11


10


8


9


10


11


30000


9


8


6


7


8


8


45000


8


7


6


6


6


5


60000


8


6


6


6


6


5

表2 水平加速飞行


V

H


1


2


3


4


5


0


11


11


11


13


15


15000


10


10


9


9


10


30000


10


9


9


10


10


45000


9


8


9


9


10


60000


7


8


8


9


9


75000


7


7


7


8


8

表3 垂直俯冲飞行


V

H


1


2


3


4


5


30000


5


4


3


3


2


45000


4


3


3


2


2


60000


3


3


2


2


2


75000


3


3


2


2


2

 根据表1~表3 的数据,欲使华夏60 战斗机从H = 0 英尺、V = 1 马赫的飞行状态达到H = 75000 英尺、V = 6马赫的飞行状态的最短飞行时间是79 秒,相应的飞行动作序列是:

恒速爬升飞行至15000 = H 英尺, 1 = V 马赫状态;

连续做两次水平加速飞行至H = 15000 英尺, V = 3 马赫状态;

连续做四次恒速爬升飞行至H = 75000 英尺, V = 3 马赫状态;

水平加速飞行至 H = 75000 英尺, V = 4 马赫状态;

连续做两次垂直俯冲飞行至H = 45000 英尺, V = 6 马赫状态;

连续做两次恒速爬升飞行至H = 75000 英尺, V = 6 马赫状态。

现在小明驾驶华夏60 战斗机以V1 马赫的速度飞行于H1 英尺高度,中队长发出了让他以V2 马赫的速度飞行于H2 英尺高度的指令。请你编写程序帮小明决策一下如何飞行才能花费最少的时间执行完中队长下达的命令。

输入:文件由四部分组成。

第一部分由一行构成,存放格式为:H1  V1  H2  V2  ?h  Hm 。

第二部分存放了表1 的内容,共有 Hm /?h 行,每行有6 列。表中第i 行、第j 列的数据表示华夏60 战斗机在 ?h*(i-1) 英尺的高度以j马赫的速度做恒速爬升飞行,飞行高度提高?h英尺所需的时间。

第三部分存放了表2 的内容,共有 Hm /?h+1 行,每行有5 列。表中第i 行、第j 列的数据表示华夏60 战斗机在 ?h*(i-1) 英尺的高度以j 马赫的初始速度做水平加速飞行,飞行速度提高1 马赫所需要的时间。

第四部分存放了表3 的内容,共有 Hm /?h-1 行,每行有5 列。表中第i 行、第j 列的数据表示华夏60 战斗机在 ?h*(i+1) 英尺的高度以j 的初始速度做垂直俯冲飞行,飞行高度降低?h英尺所需的时间。

注意:输入数据中所有的数据都是整数。

输出:

输出信息用两行来存放。第一行存放你求出的最优方案所需的时间。第二行存放该最优方案的动作序列(以R 表示恒速爬升飞行,A 表示水平加速飞行,D 表示垂直俯冲飞行)。第二行中不允许出现多余的字符(包括空白字符)。

输入

0 1 75000 6 15000 75000

12 12 12 11 12 14

11 10 8 9 10 11

9 8 6 7 8 8

8 7 6 6 6 5

8 6 6 6 6 5

11 11 11 13 15

10 10 9 9 10

10 9 9 10 10

9 8 9 9 10

7 8 8 9 9

7 7 7 8 8

5 4 3 3 2

4 3 3 2 2

3 3 2 2 2

3 3 2 2 2

输出

79

RAARRRRADDRR

一、分析问题

读完题用了很长的时间,但把它和图论联系起来想到建图的方法就不难。问题本质就是一个最短路,可以把每一个V与H的状态抽象为一个坐标点,用一维数组简化二维坐标加上队列SPFA 就水过去了O__O

二、解决问题

SPFA

三、代码实现

  1 #include<cstdio>
  2 #include<cstring>
  3 #include<queue>
  4 using namespace std;
  5
  6 const int MA=2010,inf=4e8;
  7
  8 int h1,v1,h2,v2,st,en,dh,hm,n,m,t;
  9 int sum,k;
 10 int head[MA],dis[MA],ex[MA],pre[MA],w[MA];
 11 struct edge{
 12     int t,l,n,u;
 13 }e[MA];
 14 queue<int>q;
 15 char ch[]={‘ ‘,‘R‘,‘A‘,‘D‘};
 16
 17 int calc(int a,int b)
 18 {
 19     return m*a+b;
 20 }
 21
 22 void build(int from,int to,int len,int u)
 23 {
 24     e[++sum].t=to;
 25     e[sum].u=u;
 26     e[sum].l=len;
 27     e[sum].n=head[from];
 28     head[from]=sum;
 29 }
 30
 31 void init()
 32 {
 33     scanf("%d%d%d%d%d%d",&h1,&v1,&h2,&v2,&dh,&hm);
 34     n=hm/dh;
 35     m=6;
 36     h1/=dh;st=calc(h1,v1);
 37     h2/=dh;en=calc(h2,v2);
 38
 39     for(int i=0;i<=n-1;++i)//恒速爬升
 40         for(int j=1;j<=6;++j)
 41         {
 42             scanf("%d",&t);
 43             int e=calc(i,j),f=calc(i+1,j);
 44             build(e,f,t,1);
 45         }
 46
 47     for(int i=0;i<=n;++i)//水平加速
 48         for(int j=1;j<=5;++j)
 49         {
 50             scanf("%d",&t);
 51             int e=calc(i,j),f=calc(i,j+1);
 52             build(e,f,t,2);
 53         }
 54
 55     for(int i=2;i<=n;++i)//垂直俯冲
 56         for(int j=1;j<=5;++j)
 57         {
 58             scanf("%d",&t);
 59             int e=calc(i,j),f=calc(i-1,j+1);
 60             build(e,f,t,3);
 61         }
 62 }
 63
 64 void SPFA()
 65 {
 66     for(int i=0;i<=(n+1)*m;++i)dis[i]=inf;
 67     dis[st]=0;
 68     q.push(st);
 69     while(!q.empty())
 70     {
 71         k=q.front();
 72         q.pop();
 73         ex[k]=0;
 74         for(int i=head[k];i;i=e[i].n)
 75         {
 76             if(dis[e[i].t]>=dis[k]+e[i].l)
 77             {
 78                 dis[e[i].t]=dis[k]+e[i].l;
 79                 w[e[i].t]=e[i].u;
 80                 pre[e[i].t]=k;
 81                 if(!ex[e[i].t])
 82                 {
 83                     ex[e[i].t]=1;
 84                     q.push(e[i].t);
 85                 }
 86             }
 87         }
 88     }
 89 }
 90
 91 void print(int x)
 92 {
 93     if(pre[x])print(pre[x]);
 94     if(w[x])printf("%c",ch[w[x]]);
 95 }
 96
 97 int main()
 98 {
 99     init();
100     SPFA();
101     printf("%d\n",dis[en]);
102     print(en);
103     printf("\n");
104     return 0;
105 }
时间: 2024-10-09 08:51:39

【最短路】Aircraft的相关文章

hdu 4063 Aircraft 计算几何+最短路

易知最短路一定是以圆心或者两圆交点作为中间点到达的.所以把这些点拿出来建图跑最短路就够了. 现在的问题就是,给定两个点,能否连边 add(a,b,dist(a,b)) 题目要求,ab线段必须完全在圆上,所以可以求出ab线段和所有圆的所有交点,对于任意相邻两个交点,它们必处于同一个圆内,否则不可达.点的编号用map就够了(一开始我以为double有精度问题无法map,用两个longlong保存然后乘上1000000000,后来发现没问题,应该是这题都是整点,精度要求不高的原因吧) #include

HDU 4063 Aircraft --几何,最短路

题意: 给一些圆,要求从第一个圆的圆心走到最后一个圆的圆心,中间路径必须在某个圆内,求最短路径的长度. 解法: 易知要保持在圆内且路径最短,走两圆相交的点能使路径尽量短,所以我们找出所有的两圆相交的点,再加上起点和终点,放到一个容器中,去重后,判断每两点之间的线段是否都在圆内,如果是则建边,建完所有的边后跑一个SPFA即可得出最短路. 代码: #include <iostream> #include <cstdio> #include <cstring> #includ

HDU 4063 线段与圆相交+最短路

Aircraft Time Limit: 10000/3000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 980    Accepted Submission(s): 228 Problem Description You are playing a flying game. In the game, player controls an aircraft in a 2D-

【司雨寒】最短路专题总结

最近在刷郏老大博客上的最短路专题 [HDU] 1548            A strange lift                    基础最短路(或bfs) 1 //#define LOCAL 2 #include <iostream> 3 #include <cstdio> 4 #include <cstring> 5 using namespace std; 6 7 const int maxn = 200 + 10; 8 struct Point 9

hdu4063(圆与圆交+线段与圆交+最短路)

写几何题总是提心吊胆.精度问题真心吓人. 其实思路挺简单的一道题,真是什么算法和几何double搞到一块,心里就虚虚的. 思路:求出所有圆之间的交点,然后用这些交点跑一遍最短路就可以了. Aircraft Time Limit: 10000/3000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 1244    Accepted Submission(s): 304 Proble

hdu3461Marriage Match IV 最短路+最大流

//给一个图.给定起点和终点,仅仅能走图上的最短路 //问最多有多少种走的方法.每条路仅仅能走一次 //仅仅要将在最短路上的全部边的权值改为1.求一个最大流即可 #include<cstdio> #include<cstring> #include<iostream> #include<queue> #include<vector> using namespace std ; const int inf = 0x3f3f3f3f ; const

UESTC30-最短路-Floyd最短路、spfa+链式前向星建图

最短路 Time Limit: 3000/1000MS (Java/Others) Memory Limit: 65535/65535KB (Java/Others) 在每年的校赛里,所有进入决赛的同学都会获得一件很漂亮的T-shirt.但是每当我们的工作人员把上百件的衣服从商店运回到赛场的时候,却是非常累的!所以现在他们想要寻找最短的从商店到赛场的路线,你可以帮助他们吗? Input 输入包括多组数据. 每组数据第一行是两个整数NN ,MM (N≤100N≤100 ,M≤10000M≤1000

ACM: HDU 2544 最短路-Dijkstra算法

HDU 2544最短路 Time Limit:1000MS     Memory Limit:32768KB     64bit IO Format:%I64d & %I64u Description 在每年的校赛里,所有进入决赛的同学都会获得一件很漂亮的t-shirt.但是每当我们的工作人员把上百件的衣服从商店运回到赛场的时候,却是非常累的!所以现在他们想要寻找最短的从商店到赛场的路线,你可以帮助他们吗? Input 输入包括多组数据.每组数据第一行是两个整数N.M(N<=100,M<

ACM/ICPC 之 昂贵的聘礼-最短路解法(POJ1062)

//转移为最短路问题,枚举必经每一个不小于酋长等级的人的最短路 //Time:16Ms Memory:208K #include<iostream> #include<cstring> #include<cstdio> #include<cmath> #include<algorithm> using namespace std; #define INF 0x3f3f3f3f #define MAX 105 int lim, n; int p[M