https://ac.nowcoder.com/acm/contest/21763/B

这道题已经有很多优秀的题解了,本文章不再赘述,写这篇文章主要想提到我遇到的一些情况,作为日后警醒。

我的前几次python代码是这么写的

n = int(input())
results = []
    for _ in range(n):
    
    x = int(input().strip())
    if x == 0:
        results.append("0 0")
    elif x == 1:
        results.append("1 1")
    else:
        sum = 0
        all=0
        while 1:
            if x % 2 == 1:
                sum = sum + 1
            if x >= 1:
                x = x // 2
            else:
                break
        temp=sum
        while temp:
            temp=temp-1
            all=all+2**temp
        results.append(f"{sum} {all}")
         
for result in results:
    print(result)
    

有些许多余之处,但思路大体正确,最后竟然超时了,于是我改进方法,做出了新的一版

n = int(input())
results = []
 
for _ in range(n):
    x = int(input().strip())
    if x == 0:
        results.append("0 0")
    elif x == 1:
        results.append("1 1")
    else:
        sum_ = bin(x).count('1')
        all_ = (1 << sum_) - 1      
        results.append(f"{sum_} {all_}")
for result in results:
    print(result)

这版使用了bin(x).count('1')和(1 << sum_) - 1这种较为快速简单的方式来统计二进制中1的个数和转换为十进制数,结果还是超时了。 了解之后才明白python的特点就是如果多次调用 input(),每次都会触发系统调用,当数据量极大(如 T=5e5)时,累积耗时极高。 故此处学到了一个方法 使用sys库中的sys.stdin.read()和sys.stdout.write()进行一次性输入输出 一次性读取输入:通过 sys.stdin.read() 将全部输入读入内存,避免多次系统调用。 一次性输出:用列表缓存结果后统一输出,减少 I/O 次数。 这样最终版本:

import sys
n = int(sys.stdin.readline())
results = []
 
for _ in range(n):
    x = int(sys.stdin.readline().strip())
    if x == 0:
        results.append("0 0")
    elif x == 1:
        results.append("1 1")
    else:
        sum_ = bin(x).count('1')
         
        all_ = (1 << sum_) - 1
         
        results.append(f"{sum_} {all_}")
         
for result in results:
    sys.stdout.write(result+'\n')

就以3000ms压线通过了