洞穴逃生

/************************************************************************
 
                                洞穴逃生
描述: 
    精灵王子爱好冒险,在一次探险历程中,他进入了一个神秘的山洞。在洞穴深处,精灵
    王子不小心触动了洞穴内暗藏的机关,整个洞穴将很快塌陷,精灵王子必须尽快逃离洞
    穴。精灵王子的跑步速度为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 米;
    在魔法值不够充分(M<10)的情形下,应该尽可能考虑原地休息恢复然后闪烁,按M值分三种情形:
    2、M>=6,休息1秒后(M增加了4点)闪烁,每秒移动距离是 60/2=30 米,比直接跑划算;
    3、2<=M<6,休息2秒后闪烁,每秒移动距离是 60/3=20 米,比直接跑划算;
    4、M<2,休息3秒后闪烁,这样每秒移动距离是 60/4=15 米,比直接跑移动的还少,好像没什么价值。
       不过闪烁后能至少剩下M>=2,能转换到2情形,这样两次合起来是休息5秒闪烁2次,平均每秒移动
       距离是 120/7=17.14,因此,又比直接跑要快。(^_^这种情形比较特殊,只有在剩下距离不少
       于120米的情况下适应,否则需要拆开来考虑);
    5、最后一种情形:选择直接跑。应在最后一步才选择。条件是如果剩余时间无法满足以上2和3两种
      休息后闪烁的情形,或者距离出口距离小于60米时需要在直接跑与休息后闪烁之间比较。
 
    注意第4种情形非常特别,强调条件,距离必须不少于120米,否则不能成立,这应当是考虑时最容
    易混淆出错的地方吧
 
************************************************************************/
 
 
#include <stdio.h>
 
int main() {
    int M, S, T;
    int moved = 0, time = 0; // moved 表示王子移动的距离, time 表示王子花掉的时间
    scanf("%d%d%d", &M, &S, &T);
 
    if (S == 0) {
        puts("Yes 0"); 
        return 0;
    } else if (T == 0) {
        puts("No 0"); 
        return 0;
    }
 
    while ( moved < S && time < T ) {
        if ( M >= 10) {    // 情形1:魔法值充分(大于等于10),优先闪烁
            moved += 60;
            time++;
            M -= 10;
        } else if ( M >= 6 && T - time >= 2 && S - moved > 34 ) {  // 情形2
            moved += 60;
            time += 2;
            M -= 6;  // 这里不能 M -= 10,因为休息1秒后增了4点魔法值,下同
        } else if ( M >= 2 && T - time >= 3 && S - moved > 51 ) {  // 情形3
            moved += 60;
            time += 3;
            M -= 2;
        } else if ( T - time >= 7 && S - moved >= 120 ) {   // 情形4 
            moved += 120;
            time += 7;
        } else {    // 情形5
            int n1 = T - time;
            int n2 = (S - moved + 16 ) / 17;  // 考虑剩余距离不足17m的情况,所以要加上16,不然的话就不能得到1s
            int nn = n1 < n2 ? n1 : n2;
            moved += nn * 17;
            time += nn;
        }
    }
 
    if ( moved >= S) {
        printf("Yes %d\n",time);
    } else {
        printf("No %d\n",moved);
    }
 
    return 0;
}

猜你喜欢

转载自blog.csdn.net/d710055071/article/details/47053679