首页 > 代码库 > 华夏60 战斗机(最短路dijkstra)
华夏60 战斗机(最短路dijkstra)
华夏60 战斗机(最短路dijkstra)
华夏60 超音速战斗机是当今世界上机动性能最先进的战斗机。战斗过程中的一个关键问题是如何在最短的时间内使飞机从当前的飞行高度和速度爬升/俯冲到指定的高度并达到指定速度,以便占据有利的战斗位置。
现假定只允许华夏60 执行以下三种基本飞行动作,并且只能在完成了一个基本动作的情况下再去执行另一个基本飞行动作。这样华夏60 的飞行可以表示成由这三种基本飞行动作组成的动作序列。
(1) 维持原速做恒速爬升飞行,直至飞行高度提高 ?h 英尺;
(2) 水平加速飞直至速度提高1 马赫(1 马赫 ≈ 1200 公里/小时);
(3) 垂直俯冲飞行 ?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 秒,相应的飞行动作序列是:
(1) 恒速爬升飞行至15000 = H 英尺, 1 = V 马赫状态;
(2) 连续做两次水平加速飞行至H = 15000英尺, V = 3 马赫状态;
(3) 连续做四次恒速爬升飞行至H = 75000英尺, V = 3马赫状态;
(4) 水平加速飞行至 H = 75000 英尺, V = 4马赫状态;
(5) 连续做两次垂直俯冲飞行至H = 45000英尺, V = 6马赫状态;
(6) 连续做两次恒速爬升飞行至H = 75000英尺, V = 6马赫状态。
现在小明驾驶华夏60 战斗机以V1马赫的速度飞行于H1英尺高度,中队
长发出了让他以V2马赫的速度飞行于H2英尺高度的指令。请你编写程序帮
小明决策一下如何飞行才能花费最少的时间执行完中队长下达的命令。
输入:文件由四部分组成。
(1) 第一部分由一行构成,存放格式为:H1 V1 H2 V2 ?h Hm 。
(2) 第二部分存放了表1 的内容,共有 Hm /?h 行,每行有6 列。表中第i 行、第j 列的数据表示华夏60 战斗机在 ?h*(i-1) 英尺的高度以j马赫的速度做恒速爬升飞行,飞行高度提高?h英尺所需的时间。
(3) 第三部分存放了表2 的内容,共有 Hm /?h+1 行,每行有5 列。表中第i 行、第j 列的数据表示华夏60 战斗机在 ?h*(i-1) 英尺的高度以j 马赫的初始速度做水平加速飞行,飞行速度提高1 马赫所需要的时间。
(4) 第四部分存放了表3 的内容,共有 Hm /?h-1 行,每行有5 列。表中第i 行、第j 列的数据表示华夏60 战斗机在 ?h*(i+1) 英尺的高度以j 的初始速度做垂直俯冲飞行,飞行高度降低?h英尺所需的时间。
注意:输入数据中所有的数据都是整数。Hm/?h<=50
输出:
输出信息用两行来存放。第一行存放你求出的最优方案所需的时间。第二行存放该最优方案的动作序列(以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
解题报告
光是看题目就让人不想做。但仔细分析一下,其实就是一个最短路的问题。那么怎么建模呢,这和平时的最短路有所不同。不妨把每一个状态当做一个点,包含 高度与速度两个参数,那么,表格里的每一个数据都相当于连接两个状态的一条边,权值为时间。这样最大也只会产生300个点。用堆优化的dijkstra完全可以胜任。
#include<bits/stdc++.h>#define Pair pair<int,pair<int,int> >#define MAXN 300+10#define MAXM 90000+10using namespace std;int n,m,num,head[MAXN][MAXN],dis[MAXN][MAXN],vis[MAXN][MAXN],hm,dh,pre[MAXN][MAXN];int ans[MAXN];pair<int,int> s,t;struct Edge{ int dis,next,exi,n; pair<int,int> to,from;}edge[MAXM];void add(pair<int,int> from,pair<int,int> to,int dis,int n){ edge[++num].next=head[from.first][from.second]; edge[num].to=to; edge[num].dis=dis; edge[num].n=n; edge[num].from=from; head[from.first][from.second]=num;}void dij(){ memset(dis,0,sizeof(dis)); memset(vis,0,sizeof(vis)); priority_queue<Pair,vector<Pair>,greater<Pair> > h; for(int i=0;i<=6;i++) for(int j=0;j<=m;j++) dis[i][j]=2147483647; dis[s.first][s.second]=0; h.push(Pair(dis[s.first][s.second],s)); while(h.size()>0) { pair<int,int> k=h.top().second;h.pop(); if(vis[k.first][k.second]) continue; vis[k.first][k.second]=1; for(int i=head[k.first][k.second];i;i=edge[i].next) if(dis[k.first][k.second]+edge[i].dis<=dis[edge[i].to.first][edge[i].to.second]) { dis[edge[i].to.first][edge[i].to.second]=dis[k.first][k.second]+edge[i].dis; pre[edge[i].to.first][edge[i].to.second]=i; h.push(Pair(dis[edge[i].to.first][edge[i].to.second],edge[i].to)); } }}int main(){ freopen("airfract.in","r",stdin); freopen("airfract.out","w",stdout); scanf("%d%d%d%d%d%d",&s.second,&s.first,&t.second,&t.first,&dh,&hm); m=hm/dh;s.second/=dh;t.second/=dh; for(int h=0;h<=m-1;h++) { for(int v=1;v<=6;v++) { int x; pair<int,int> a,b; scanf("%d",&x); a.first=v;a.second=h; b.first=v;b.second=h+1; add(a,b,x,‘R‘); } } for(int h=0;h<=m;h++) { for(int v=1;v<=5;v++) { int x;pair<int,int> a,b; scanf("%d",&x); a.first=v;a.second=h; b.first=v+1;b.second=h; add(a,b,x,‘A‘); } } for(int h=2;h<=m;h++) { for(int v=1;v<=5;v++) { int x;pair<int,int> a,b; scanf("%d",&x); a.first=v;a.second=h; b.first=v+1;b.second=h-1; add(a,b,x,‘D‘); } } dij(); printf("%d\n",dis[t.first][t.second]); for(int i=pre[t.first][t.second];i;i=pre[edge[i].from.first][edge[i].from.second]) ans[++ans[0]]=edge[i].n; for(int i=ans[0];i>=1;i--) { printf("%c",ans[i]); }printf("\n"); return 0;}
华夏60 战斗机(最短路dijkstra)