统计数字

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

用 map 统计每个数字出现次数,按键升序输出。

OJ: roj

题目 ID: 1239

难度:入门

标签:哈希表排序计数

创建: 2026-09-30 01:08

更新: 2026-10-05 06:19

题目描述

科研调查得到 nn 个自然数(1≤n≤2000001 \le n \le 200000,每数 ≤1.5×109\le 1.5 \times 10^9,不同值不超过 1000010000 个),统计每个不同值的出现次数并按值从小到大输出。第一行 nn,接下来 nn 行每行一个自然数;输出 mm 行,每行「值 次数」。完整样例见 problem.md。

思路

用 map<ll,int> 边读边累加计数,键天然升序,最后顺序遍历输出即可,复杂度 O(nlog⁡m)O(n \log m)。

参考代码

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-30 01:12
# update_at: 2026-09-30 01:12

import sys
from collections import Counter


def solve() -> None:
    """读入所有数字,统计频次后按数值升序输出。"""
    data = map(int, sys.stdin.buffer.read().split())
    n = next(data)                                  # 自然数个数
    counts = Counter(data)                            # 每个数字的出现次数
    out = '\n'.join(f'{v} {c}' for v, c in sorted(counts.items()))
    sys.stdout.write(out)


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 06:19
 * update_at: 2026-10-05 06:19
 */

#include <cstdio>
#include <map>
using namespace std;

typedef long long ll;

const int MAXN = 200005;

ll a[MAXN];        // 读入的 n 个自然数

int main() {
    int n;
    scanf("%d", &n);
    // 用 map 自动按键升序排列,一边读一边统计每个值出现次数
    map<ll, int> cnt;
    for (int i = 1; i <= n; ++i) {
        scanf("%lld", &a[i]);
        cnt[a[i]]++;
    }
    // map 已经按 ll 升序排好,直接按顺序输出
    for (auto it = cnt.begin(); it != cnt.end(); ++it) {
        printf("%lld %d\n", it->first, it->second);
    }
    return 0;
}