腾讯笔试题 两个数经过几次加一和乘二运算变成另两个数

本文介绍了一种通过按红色按钮使两数同时加1、按蓝色按钮使两数同时乘2来达到特定目标值的算法。该算法的目标是找出达到指定数值所需的最少操作次数,并附带了一个具体实例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

问题描述

(大概是这样的,逻辑肯定是没问题的,描述可能有些区别)
—–小明有一个红色按钮和一个蓝色按钮,按一下红色按钮,第一个数和第二个数同时加1,按一下蓝色按钮,第一个数和第二个数同时乘2,问:至少需要按几次按钮,第一个数和第二个数分别变成第三个数和第四个数?

输入输出

100 1000 202 2002
2

—–第一行表示输入的四个数,第二行表示的是要进行运算的次数

话不多说上硬货

import time


def log2(x):
    t = 0
    while x != 1:
        x /= 2
        t += 1
    return t


if __name__ == '__main__':
    times = 0
    a, b, A, B = [int(x) for x in raw_input('Input four numbers,split with space:\n').split(' ')]
    start_time = time.clock()
    if a == 0 and b == 0:
        if A == B:
            times = A
        else:
            times = -1
    elif a == 0 and B - A == b:
        times = A
    elif b == 0 and A - B == a:
        times = B
    else:
        m1, m2, p1, p11, p2, p22, res1, res2 = 0, 0, 0, 0, 0, 0, 0, 0
        m1 = log2(A / a)
        m2 = log2(B / b)
        if A % a == 0 and B % b == 0:
            p1 = A / 2 ** m1 - a
            p2 = B / 2 ** m2 - b
            if p1 == p2 and m1 == m2:
                times = m1 + p1
            else:
                times = -1
        elif A % a != 0 and B % b != 0:
            p1 = A / 2 ** m1 - a
            p2 = B / 2 ** m2 - b
            res1 = A % 2 ** m1
            res2 = B % 2 ** m2
            if p1 == p2 and m1 == m2 and res1 == res2:
                times = m1 + p1 + res1
            else:
                times = -1
    print times
print("--- %s seconds ---" % (time.clock() - start_time))

心路历程

—–第一次看到上面这个例子,第一印象就是这个例子不好,不利于我们思考,所以我换了个例子
3 4 22 26这四个数。想一想,如何获取最少的运算次数,那应该尽量多进行乘2运算,因此只要求出乘2的最大次数就可以了,这个也就是3×最大乘2次数=22。用公式表示出来就是
(3+第一次加一的次数)× 2 (幂:乘2的次数)+ 第二次加一的次数
实际例子就是(3+1+1)*2**2+1+1
按照上面的思想,用p1,p2表示第一次加一的次数,m1,m2表示乘2的次数,res1,res2表示第二次加一的次数,如果前两次刚好能得到第三第四个数,就不需要进行第二次加1。
描述的可能有点乱,不知道怎么用这个markdown写公式,在下面贴出手稿,会清楚很多。

这里写图片描述
这里写图片描述

算法复杂度和运行时间

时间复杂度O(1)
空间复杂度O(1)
运行时间:6e-05 seconds也就是0.00006s,完全符合时间要求的。
时间复杂度和空间复杂度我认为是这样的,我也是一名Python beginner ,如有问题,欢迎留言。

评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值