华为机试——洞穴逃生
华为机试——洞穴逃生
描述: 精灵王子爱好冒险,在一次探险历程中,他进入了一个神秘的山洞。在洞穴深处,精灵王子不小心触动了洞穴内暗藏的机关,整个洞穴将很快塌陷,精灵王子必须尽快逃离洞穴。精灵王子的跑步速度为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.在魔法值充分(M>=10)的情况下,优先连续使用闪烁,每秒移动距离是60/1=60米 在魔法值不充分的情况下,应尽量考虑原地休息,恢复魔法值后再次使用闪烁 2.M>=6,休息1s,使用闪烁1s,每秒移动距离是60/2=30米 3.2=<M<6,休息2s后使用闪烁,每秒移动距离是60/3=20米,比直接跑速度快 4.M<2,休息3s后使用闪烁,每秒移动距离是60/4=15米<17,好像没什么价值 不过使用闪烁后剩余的M>=2,转到情形3,加上2s的休息,总共需要7s,每秒移动距离为120/7=17.14米 比直接跑快(这种特殊情况只有在距离洞口120时才能使用) 5.最后一种情形,选择直接跑,应在最后一步才选择。条件是如果剩余时间无法满足2和3两种休息后使用闪烁的情况,或者 距离出口距离小于60米时需要在直接跑和休息后闪烁之间比较。 */ #include<iostream> using namespace std; int main() { int M,S,T; int moved=0,time=0; cin>>M>>S>>T; if(S==0) { cout<<"Yes 0"<<endl; return 0; } else if(T==0) { cout<<"No 0"<<endl; return 0; } while(moved < S && time<T) { if(M >=10) { moved += 60; time++; M -= 10; } else if(M >= 6 && time +2 <=T && moved+34 < S) { moved += 60; time+=2; M -= 6; //因为休息1秒后增加了4点魔法值。 } else if(M>=2 && time+3 <=T && moved +17*3 <S) { moved += 60; time += 3; M=M+8-10; } else if(time + 7 <=T && S - moved >=120) { moved += 120; time+=7; } else { int t1=T-time; int t2=(S-moved +16 )/17; //考虑剩余距离不足17m的情况,所以要加上16,不然的话就不能得到1s int tt=t1<t2 ? t1:t2; moved += tt*17; time += tt; } } if(moved >=S) { cout<<"Yes "<<time<<endl; } else { cout<<"No "<<moved<<endl; } return 0; }