上电梯问题

  公司新建一幢大厦,有很多楼层。现设计师觉得每个电梯都又所有的楼层的按钮太麻烦了,因此将电梯设计成只有两个按钮,第i个电梯有两个按钮,一个按钮uiUp,表示上升uiUp层,一个为uiDown,表示下降uiDown层。

  我们假设电梯永远到不了顶层,但电梯最低为0层。所有电梯初始都在第0层。

   现有共m个电梯,你可以选择其中一个,但是选取之后就不能变换电梯了,当你走进这座大楼,按n次电梯按钮后,电梯最低能够停在几层。

思路一:很自然的想法,如果现在上升的楼数大于一次能下降的楼数,则下降,反之则往上增加一次上升。代码粘帖如下:

#include <stdio.h>
#include <stdlib.h>

#define IN
#define INT int
#define UINT unsigned int

#define MIN(uiA, uiB) ((uiA) < (uiB) ? (uiA) : (uiB))

UINT computer_elevator(IN UINT uiM, IN UINT uiN, IN UINT uiUp, IN UINT uiDown);
UINT cd_elevator(IN UINT uiM, IN UINT uiN, IN UINT auiUp[], IN UINT auiDown[]);

INT main()
{
    UINT auiArr[3] = {15, 15, 7};    
    UINT auiBrr[3] = {12, 4, 12};
    printf("-----:%d\n", cd_elevator(3, 10, auiArr, auiBrr));
    return 0;
}

UINT computer_elevator(IN UINT uiM, IN UINT uiN, IN UINT uiUp, IN UINT uiDown)
{
    UINT uiUpSum = uiUp;
    
    printf("uiM: %d   ", uiM);
    printf("up   ");
    uiN--;
    while (0 != uiN)
    {
        while ((uiUpSum >= uiDown) && (0 != uiN))
        {   
            printf("down  ");
            uiUpSum = uiUpSum - uiDown;
            uiN--;
        }
        if (0 != uiN)
        {
            printf("up   ");
            uiUpSum = uiUpSum + uiUp;
            uiN--;
        }
    }
    printf("uiUpSum = %d\n", uiUpSum);
    
    return uiUpSum;
}

//其中uiM 表示电梯数目,uiN表示按钮次数,auiUp[i]为第i个电梯一次上升的层数,auiDown[i]为第i个电梯一次下降的层数
UINT cd_elevator(IN UINT uiM, IN UINT uiN, IN UINT auiUp[], IN UINT auiDown[])
{
    UINT uiTempMin = 0;
    UINT uiMin = computer_elevator(1, uiN, auiUp[0], auiDown[0]);
    
    while (1 != uiM)
    {
        uiTempMin = computer_elevator(uiM, uiN, auiUp[uiM - 1], auiDown[uiM - 1]);
        uiMin = MIN(uiMin, uiTempMin);
        uiM--;
    }
    
    return uiMin;
}



思路二 使用数学公式推导

auiUp * UpNum - auiDown*DownNum >=0  (1)

UpNum + DownNum = Num  (2)

将 (2)式代入 (1)式中,得到 DownNum <= auiUp*Num / (auiUp + auiDown),要使上升层数最少,则DownNum最大,即刚好是最大整数,代码如下


#include <stdio.h>
#include <stdlib.h>

#define IN
#define INT int
#define UINT unsigned int

#define MIN(uiA, uiB) ((uiA) < (uiB) ? (uiA) : (uiB))

inline UINT computer_elevator(IN UINT uiM, IN UINT uiN, IN UINT uiUp, IN UINT uiDown);
UINT cd_elevator(IN UINT uiM, IN UINT uiN, IN UINT auiUp[], IN UINT auiDown[]);

INT main()
{
    UINT auiArr[3] = {15, 15, 7};    
    UINT auiBrr[3] = {12, 4, 12};
    printf("-----:%d\n", cd_elevator(3, 10, auiArr, auiBrr));
    return 0;
}

inline UINT computer_elevator(IN UINT uiM, IN UINT uiN, IN UINT uiUp, IN UINT uiDown)
{
    UINT uiDownTime = uiUp * uiN / (uiUp + uiDown);
    return uiUp * (uiN - uiDownTime) - uiDown * uiDownTime;
}

UINT cd_elevator(IN UINT uiM, IN UINT uiN, IN UINT auiUp[], IN UINT auiDown[])
{
    UINT uiMinTemp = 0;
    UINT uiMin = computer_elevator(1, uiN, auiUp[0], auiDown[0]);    

    while (1 != uiM)
    {
        uiMinTemp = computer_elevator(uiM, uiN, auiUp[uiM - 1], auiDown[uiM - 1]);
        uiMin = MIN(uiMin, uiMinTemp);
        uiM--;
    }
    
    return uiMin;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值