跳转至

PIO6 单组_一维数组

入门通过率 48.6%python3样例通过牛客 AC

牛客原题  源码

讲解章节推导式输入输出处理

一句话

先读长度 n,再读 n 个数,求和。

解题思路

这题考什么

输入形态:单组数据,带前导数量。第一行的 n 是「后面有多少个数」的说明, 第二行才是数据本体。这种「先给个数,再给数据」的排布是竞赛题的标配。

Python 里 n 通常用不上:split() 已经把整行切成了列表, 列表自己知道有多长,不需要靠 n 来控制循环。所以第一行读进来直接丢掉。 注意「丢掉」不等于「不读」——那一行必须消费掉, 否则接下来的 input() 拿到的是 n 那一行而不是数据行。

求和用 sum(map(int, ...)):map 和 sum 的循环都发生在解释器的 C 层, 换成 Python 的 for 循环逐个累加,同样的 1e5 个数要多走 1e5 轮字节码。

为什么这里 input() 还够用

input() 的开销按调用次数计,与单次读入的字节数关系不大。 本题总共只有两行,也就只调用两次,哪怕第二行有 1e5 个数也只是一次调用。 真正需要换成 sys.stdin.buffer.read() 的是行数上万的多组题(见 PIO7)。

数据规模与复杂度

n <= 1e5,每个 a_i <= 1e9,所以和最大 1e5 * 1e9 = 1e14。 1e14 远超 32 位整数上限,C/C++ 需要 long long,Python 的 int 任意精度, 不必操心。时间 O(n),空间 O(n)(split 出来的列表)。

坑在哪

  1. 第一行不能不读。少读一次,第二行的 split() 会作用在「n」那一行上, 结果输出成 n 本身。
  2. 别为了「用上 n」而写 for i in range(n) 逐个 int(), 那是把 C 层循环换成 Python 层循环,只会更慢。
  3. 和可能达到 1e14,用其他语言抄这份思路时要记得换成 64 位整数类型。

参考实现

solutions/PIO6.py
input()                                   # 读掉 n 那一行;Python 中长度信息用不上,但行必须消费
print(sum(map(int, input().split())))     # map + sum 都在 C 层跑完,比 Python 循环累加快
[:octicons-arrow-left-16: PIO5](PIO5.md) [PIO7 :octicons-arrow-right-16:](PIO7.md)