code200这道题应该算是一道送分的大水题吧,题目意思很明确,不需要去猜,然后做法也很简单。
题目描述如下:
在218.2.197.248:10007运行了一个ATM程序,但是这个ATM有一个特点,每次只能存2^i(i为偶数)元或者取2^i(i为奇数)元,0<=i<99,且每个i只能使用一次。给出任意一定的金额(正数代表取出,负数代表存进),怎样操作这个ATM才能满足给定的金额? eg: 13 4 3 2 0 983 10 5 3 1 0
话说这道题,赛后看样例的时候,突然发现,题目写反了,4 3 2 0 对应的应该是 – 2^4 + 2^3 – 2^2 – 2^0 = -13。
不要在意这些细节,我们继续看……
很显然,我们可以先考虑正数的情况,负数就是类似的做即可。
拿到的第一想法肯定是对要求的金额进行二进制分解,这样得到的东西,显然是不能直接过的,其中2^i(i为奇数)的情况是只能取,不能存。那么,我们就要将2^i(i为奇数)替换成存2^(i+1)并取2^i,然后这样一路向上传递上去,便得以解决。
得到程序如下:
#!/usr/bin/env python
#encoding:utf-8
import socket
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect(('218.2.197.248', 10007))
round_count = 1
while True:
aim = s.recv(100)
# aim = '-809'
while aim == '':
aim += s.recv(100)
aim = int(aim)
print aim
sign = int(aim < 0)
aim = abs(aim)
bin_aim = bin(aim)[2:][::-1]
bin_aim_len = len(bin_aim)
bin_aim = [bool(c == '1') for c in (bin_aim + '0' * (100 - len(bin_aim)))]
# print bin_aim
ans = []
for i in xrange(99):
if bin_aim[i]:
if i % 2 == sign:
pass
else:
j = i + 1
while bin_aim[j]:
bin_aim[j] = False
j += 1
bin_aim[j] = True
ans = ''
for i in xrange(99, -1, -1):
if bin_aim[i]:
ans += str(i) + ' '
print ans
s.send(ans[:-1])
# break
round_count += 1
print 'Round', round_count