洞穴逃跑-精灵王子

//精灵王子在一个快要坍塌的洞穴,他必须尽快逃离。
//他跑步速度为17m/s,以跑步速度无法逃出。

//他拥有闪烁法术,在1s内移动60m,但每次会消耗魔法值10点。魔法值恢复的速度是4点/s,在原地休息才能恢复。


//已知:魔法初始值M,离洞口的距离S,距离洞穴坍塌的时间T。
//若能逃出,输出“yes”,并输出逃出所用最短时间;若不能,输出no,并输出走的距离。




思路分析:
    王子的状态有以下几种情形:
    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,能转换到3情形,这样两次合起来是休息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;
//M值先加后减,没有数值变化
        } 
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;
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值