问题描述
(大概是这样的,逻辑肯定是没问题的,描述可能有些区别)
—–小明有一个红色按钮和一个蓝色按钮,按一下红色按钮,第一个数和第二个数同时加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 ,如有问题,欢迎留言。