第六届华为创新杯编程大赛-进阶1第1轮 洞穴逃生 (bfs + 优先队列)

这个题容易出错想了挺长时间,然后代码不长,1Y..

做完题,看了一下别人的博客,也可以优先用 闪烁法术, 在闪烁法术不不如跑步的阶段(即魔法恢复的时候)用跑步。

 

洞穴逃生
描述:

精灵王子爱好冒险,在一次探险历程中,他进入了一个神秘的山洞。在洞穴深处,精灵王子不小心触动了洞穴内暗藏的机关,整个洞穴将很快塌陷,精灵王子必须尽快逃离洞穴。精灵王子的跑步速度为17m/s,以这样的速度可能是无法逃出洞穴的。庆幸的是精灵王子拥有闪烁法术,可在1s内移动60m,不过每次使用闪烁法术都会消耗魔法值10点。精灵王子的魔法值恢复的速度为4点/s,只有处在原地休息状态时才能恢复。

现在已知精灵王子的魔法初值M,他所在洞穴中的位置与洞穴出口之间的距离S,距离洞穴塌陷的时间T。你的任务是写一个程序帮助精灵王子计算如何在最短的时间内逃离洞穴。若能逃出,输出"Yes",并输出逃出所用的最短时间;若不能逃出,则输出"No",同时输出精灵王子在剩下的时间内能走的最远距离。注意字母大小写。注意:精灵王子跑步、闪烁或休息活动均以秒(s)为单位。且每次活动的持续时间为整数秒。距离的单位为米(m)。

注:M、S、T均是大于等于0的整数。由输入保证取值合法性,考生不用检查。

提醒:

如果输入的S为0,则说明本身已经在出口,输出应为:Yes 0

如果输入的T为0(且S不为0),则说明已经没有时间了,输出应为:No 0

 

运行时间限制:无限制
内存限制:无限制
输入:

输入格式:
M
S
T

输出:

输出格式:
Yes 逃出洞穴所用的最短时间

No 在洞穴塌陷前能逃跑的最远距离

样例输入:
10

50

5
样例输出:
Yes 1

 

 

思路:每一秒都有三种选择, 1、以17m/s 跑。  2、消耗10魔法值, 60m/s。    3、原地等待, 恢复4魔法值。

注意必须用优先队列

 1 #include <iostream>
 2 #include <cstring>
 3 #include <cstdio>
 4 #include <cstdlib>
 5 #include <queue>
 6 #include <cmath>
 7 #include <algorithm>
 8 using namespace std;
 9 bool vis[6000][100][100];
10 int m, s, t, ans_s;
11 int dx[4] = {17, 60, 0};
12 int dy[4] = {0, -10, 4};
13 
14 struct node
15 {
16     int dis, tt, mm;
17     bool operator < (const node &tmp)const
18     {
19         return dis > tmp.dis;
20     }
21 } pos, next;
22 void bfs()
23 {
24     int i;
25     queue<node>q;
26     memset(vis, 0, sizeof(vis));
27     next.dis = 0;
28     next.tt = 0;
29     next.mm = m;
30     vis[0][0][m] = true;
31     q.push(next);
32     ans_s = -1;
33     while(!q.empty())
34     {
35         pos = q.front();
36         q.pop();
37         for(i = 0; i < 3; i++)
38         {
39             next.dis = pos.dis + dx[i];
40             next.tt = pos.tt + 1;
41             next.mm = pos.mm + dy[i];
42             if(i == 1 && next.mm < 0)  //第二种情况必须有10魔法值
43             continue;
44             if(i == 2 && pos.mm/10*60 + pos.dis >= s) //第三种如果魔法值已经够逃出洞穴,就不要再攒了
45             continue;
46             if(next.tt > t)
47             continue;
48             if(next.dis >= s)
49             {
50                 printf("Yes %d\n", next.tt);
51                 return;
52             }
53             if(next.tt == t && next.dis > ans_s) //如果时间正好,但是距离没有达到,就记录一下
54             ans_s = next.dis;
55             if(!vis[next.dis][next.tt][next.mm])
56             {
57                 vis[next.dis][next.tt][next.mm] = true;
58                 q.push(next);
59             }
60         }
61     }
62     printf("No %d\n", ans_s);
63 }
64 int main()
65 {
66     while(~scanf("%d%d%d", &m, &s, &t))
67     {
68         if(s==0)
69         {
70             printf("Yes 0\n");
71             continue;
72         }
73         if(t==0)
74         {
75             printf("No 0\n");
76         }
77         bfs();
78     }
79     return 0;
80 }

 

转载于:https://www.cnblogs.com/bfshm/p/3713321.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值