【招商银行信用卡实习笔试补充】nod 1483-化学试剂-使用python

原题连接:http://www.51nod.com/Challenge/Problem.html#!#problemId=1483

有n种不同的化学试剂。第i种有ai升。每次实验都要把所有的化学试剂混在一起,但是这些试剂的量一定要相等。所以现在的首要任务是把这些化学试剂的量弄成相等。

有两种操作:

  1. 使其剂量翻倍
  2. 使其剂量减半(其实题目是对2取整)

问多少次操作后,可以将所有瓶中试剂含量相等。(1<n<10^5, 1<ai<10^5)

原本的解法在nod上验证以后,发现只通过了80%左右,发现还是考虑不周全

  1. 没考虑50,100这种倍数关系
  2. 没考虑98,99这种可以经过若干次/2以后变为相同的情况
  3. 以及其他没想到的情况

只在原来基础上考虑了情况1的时候:

num_2n = [2**n for n in range(17)]
count = 0
des = list()
n = int(input())
num = [int(i) for i in input().split()]
num.sort()
timesFlag = True
for i in range(1,n):
    if num[i]%num[0]==0 and num[0] not in num_2n:
        count += num[i]//num[0]-1
    else:#一旦不全是倍数关系,则进行2^n求解过程
        timesFlag = False
        count = 0
        break
if timesFlag==False:
    for i in range(n):
        while num[i] not in num_2n:
            num[i] = num[i]//2
            count += 1
        des.append(num_2n.index(num[i]))
    a = sum(des)//n
    for i in des:
        count += abs(a-i)
print(count)

提交后,发现还是只通过了19/20。头疼的是nod下载测试用例要什么币……

后来,受同学启发,还是采用暴力枚举法来解题,大概思想是:

  1. 把每个输入的数经过 乘2 或者 对2取整 的操作能达到的值全都记录下来,并且记录到该值需要的操作步骤。
  2. 然后找出【所有输入的数【都能达到的值】】
  3. 在其中(都能到达的值)找出操作数之和最小的值,其操作数即为正解。

代码如下:

n = int(input())
numList = [int(i) for i in input().split()]
cnt = [0]*(10**5+1)
arrive = [0]*(10**5+1)
rch = []
for num in numList:
    tmp = num
    opd = 0     # 操作数
    while tmp <= 10**5:      # 先乘
        cnt[tmp] += opd
        arrive[tmp] += 1
        tmp *= 2
        opd += 1
    opd = 0
    tmp = num
    while tmp != 0:
        if tmp%2 != 0 and tmp != 1:     # 奇数
            tmp //= 2
            opd += 1
            cnt[tmp] += opd
            arrive[tmp] += 1
            # 奇数对2取整,在*2会产生新值。
            ttmp = tmp
            topd = opd
            ttmp *= 2
            topd += 1
            while(ttmp <= 10**5):
                cnt[ttmp] += topd
                arrive[ttmp] += 1
                ttmp *= 2
                topd += 1
        else:
            tmp //= 2
            opd += 1
            cnt[tmp] += opd
            arrive[tmp] += 1  # 标记num能够到达tmp
for i in range(1,10**5+1):
    if arrive[i] == n:
        rch.append(cnt[i])
print(min(rch))

代码提交到nod以后,有2例超时,这个时候python的短板就体现出来了……

猜你喜欢

转载自blog.csdn.net/jitanban0579/article/details/89195491