整数的个数

GitHub跳转原题关系图返回列表

值域极小的桶计数:一趟扫描只对 1、5、10 三个目标值各维护一个计数器,非目标值一律忽略。

OJ: roj

题目 ID: 1067

难度:入门

标签:桶计数入门

创建: 2026-09-29 17:08

更新: 2026-10-05 00:05

题目描述

给定 kk(1<k<1001 < k < 100)个正整数,每个数都在 11 到 1010 之间。统计其中 11、55、1010 各出现的次数。

输入有两行:第一行是正整数 kk,第二行是用空格分开的 kk 个正整数。输出有三行,依次为 11、55、1010 出现的次数。

样例输入:

text
5
1 5 8 10 5

样例输出为三行:1、2、1。

思路

读入 kk 个数,维护计数器 cnt1、cnt5、cnt10,每个数与三个目标值做相等比较,命中就加一,其余值忽略。这是值域极小时的桶计数:扫一遍序列即可,时间 O(k)O(k),输出按 11、55、1010 的顺序。

参考代码

Python 版:

python
#!/usr/bin/env python3
# Author by Rainboy blog: https://rainboylv.com github: https://github.com/rainboylvx
# rbook: -> https://rbook.roj.ac.cn  https://rbook2.roj.ac.cn
# rainboy的学习导航网站: https://idx.roj.ac.cn
# create_at: 2026-09-29 17:08
# update_at: 2026-09-29 17:08

import sys

TARGETS = (1, 5, 10)  # 题面要求统计的三个整数


def solve() -> None:
    data = iter(map(int, sys.stdin.buffer.read().split()))
    k = next(data)  # 正整数的个数
    nums = [next(data) for _ in range(k)]

    # 桶计数:cnt[v] = 值 v 出现的次数;不在 1..10 范围的值不影响三个目标值
    cnt = {v: nums.count(v) for v in TARGETS}

    print('\n'.join(map(str, (cnt[1], cnt[5], cnt[10]))))


if __name__ == "__main__":
    solve()

C++ 版(同一算法):

cpp
/**
 * Author by Rainboy blog: https://rainboylv.com github: https://github.com/rainboylvx
 * rbook: -> https://rbook.roj.ac.cn  https://rbook2.roj.ac.cn
 * rainboy的学习导航网站: https://idx.roj.ac.cn
 * create_at: 2026-10-05 00:05
 * update_at: 2026-10-05 00:05
 */

#include <cstdio>

typedef long long ll;

ll k;      // 正整数的个数
ll cnt1;   // 1 出现的次数
ll cnt5;   // 5 出现的次数
ll cnt10;  // 10 出现的次数

int main() {
    scanf("%lld", &k);
    for (ll i = 1; i <= k; ++i) {
        ll x;
        scanf("%lld", &x);
        // 只统计三个目标值,其余数(如样例中的 8)一律忽略
        if (x == 1) cnt1++;
        if (x == 5) cnt5++;
        if (x == 10) cnt10++;
    }
    // 按 1、5、10 的固定顺序分三行输出
    printf("%lld\n%lld\n%lld\n", cnt1, cnt5, cnt10);
    return 0;
}