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压线通过了