出现次数超过一半的数

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

一遍哈希计数取众数,用整数不等式 2*times > n 判定严格过半,避开浮点与整除两类半判定错误。

OJ: roj

题目 ID: 1186

难度:入门

标签:入门计数哈希表python

创建: 2026-09-29 22:37

更新: 2026-10-05 04:41

题目描述

给定 nn(0<n⩽10000 < n \leqslant 1000)个整数 a1,…,ana_1, \dots, a_n(−50<ai<50-50 < a_i < 50),若存在某个值出现次数严格超过一半则输出这个数,否则输出 no。

第一行 nn,第二行 nn 个整数。样例:3 / 1 2 2 → 2。

思路

一遍哈希计数得到每个值的出现次数,取最大值;若 2 * times > n(严格过半)则输出该值,否则 no。

参考代码

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 22:45
# update_at: 2026-10-04 10:18

import sys
from collections import Counter


def solve() -> None:
    data = iter(map(int, sys.stdin.buffer.read().split()))
    n = next(data)  # 数组大小
    count = Counter(next(data) for _ in range(n))  # 每个值的出现次数
    value, times = max(count.items(), key=lambda kv: kv[1])  # 众数及其次数
    # 超过一半:times / n > 1/2 等价于 2 * times > n,用乘法避免浮点
    print(value if 2 * times > n else "no")


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 04:41
 * update_at: 2026-10-05 04:41
 */

#include <iostream>
using namespace std;

typedef long long ll;

const int OFFSET = 50;          // 把 -49..49 平移到 0..98 的桶偏移
const int MAXB = 100;           // 桶数量,覆盖值域 [-49, 49] 共 99 个值

int cnt[MAXB];                  // cnt[i] 表示值 (i - OFFSET) 出现的次数

int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);

    int n;
    if (!(cin >> n)) return 0;  // 数组大小
    for (int i = 0; i < n; ++i) {
        int x;
        cin >> x;               // 读入数组元素
        cnt[x + OFFSET]++;      // 桶计数
    }

    // 找出现次数最多的值
    int best_id = 0;            // 众数对应的桶下标
    for (int i = 0; i < MAXB; ++i) {
        if (cnt[i] > cnt[best_id]) best_id = i;
    }
    int times = cnt[best_id];   // 众数出现次数
    int value = best_id - OFFSET; // 还原为真实数值

    // 严格过半:times / n > 1/2 等价于 2 * times > n,整数比较避免浮点
    if (2 * times > n) cout << value << "\n";
    else cout << "no\n";

    return 0;
}