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