Itertools.combinations()超出了时间限制

时间:2020-02-24 21:45:08

标签: python python-3.x performance

我正在尝试解决此Python编码问题:

说明:Ambrosio老师正在向他的老师教授二进制数 女儿Ambrosinita,所以他决定创建一个游戏。

Ambrosio将把N个数字提供给Ambrosinita,后者可以选择K个数字 首字母N中的一个。她选择的每个数字都会得到一个分数 等于1的数量(使用的二进制表示形式) 数字。

帮助Ambrosinita找出她可以赚取多少积分。

条目:

第一行输入包含整数T,该整数表示数字 测试用例。

每个测试用例都从包含整数N(总数)的行开始 和K(可以选择的数字)。

每种情况的最后一个输入行包含N个整数,代表 Ambrosinita可以选择的数字。

输出:

对于每个测试用例,打印一行包含Ambrosinita多少点的行 可以赚。

1≤T≤10

1≤N≤10 ^ 3

0≤K≤N

0≤数字≤10^ 5

执行时间限制为2秒。我遇到了TLE错误,但输出与预期的相同。因此,输入必须具有一定的长度。

这是我的代码:

import itertools

test_cases = int(input())

def binary(num):
    return format(num,'b')

def filter_string_1s(string):
    aux = ''
    for i in string:
        if i == '1':
            aux += i
    return aux

for i in range(test_cases):
    k = input().split()
    k = int(k[1])
    values = input().split()
    values = [int(i) for i in values]
    values = [filter_string_1s(str(binary(i))) for i in values]
    bin_values = []
    for combination in itertools.combinations(values,k):
        aux = 0
        for bin_number in combination:
            for i in bin_number:
                if i == '1':
                    aux += 1
        bin_values.append(aux)
    print(max(bin_values))

问题:为了在执行时限内解决问题,我应该采取哪些步骤对其进行优化?

TLE =超过时间限制

3 个答案:

答案 0 :(得分:1)

这是一个“ top-k”问题,不是需要“ k”组合的问题。为了便于阅读,我们选择N = 990,K =7。您需要在990列表中选择前7个得分。

您通过生成C(990,7)= 912,459,983,564,271,542,400组合并然后确定每种组合中的7个数字中有多少1位来做到这一点。这就是为什么时间不够用的原因:您需要考虑990个数字,但是对于输入中的每个数字,您要重复进行数万亿比特的计数。

敲开它。您需要做的是一次遍历该列表,并保留前7位。列表中的7个数字之间没有相互作用。实际上,您甚至不必报告数字,只需报告总成绩即可。

从七个零的列表开始。现在遍历所有990个数字。每当您发现位数大于列表中的最小元素时(保持排序以便于参考),然后将其替换为新分数(并重新排序)。在所有990个数字的末尾,sum列表。

计数位数比您做的要容易得多。将int转换为二进制字符串,然后使用str.count(1)查看其中有多少1位。

答案 1 :(得分:0)

她可以取得的最大分数是选择具有最高1位的K个数字。因此,您只需要计算每个数字的点并取顶K即可。

例如:

import random

def maxPoints(K,N=None,numbers=None):
    numbers = numbers or [random.randrange(0,100001) for _ in range(N)]
    points  = sorted(bin(n).count("1") for n in numbers)
    return sum(points[-K:])

mp = maxPoints(3,numbers=[1,2,3,4,5])
print(mp) # 5

mp = maxPoints(1000,1000) 
print(mp) # will return instantly

答案 2 :(得分:0)

解决了!谢谢大家。

代码:

test_cases = int(input())

for i in range(test_cases):
    k = input().split()
    k = int(k[1])
    nums = input().split()
    nums = [format(int(i),'b').count('1') for i in nums]
    nums.sort()
    sum = 0
    for i in range(k):
        sum += nums[-1]
        del nums[-1]
    print(sum)
相关问题