年龄与疾病

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

三个右端点 18/35/60 把年龄切成四段,年龄严格越过几个端点就属于第几段,再按段统计百分比。

OJ: roj

题目 ID: 1106

难度:入门

标签:入门计数格式化输出python

创建: 2026-09-29 19:05

更新: 2026-10-05 01:15

题目描述

某医院要整理诊断记录,按 0-18、19-35、36-60、61 以上(含 61)四个年龄段,统计各段患病人数占总患病人数的百分比。 输入两行:第一行为病人数 nn(0<n⩽1000 < n \leqslant 100),第二行为 nn 个病人的年龄。 输出四行,依次为四个年龄段的人数占比,写成百分比形式并保留两位小数。 样例输入第一行 10、第二行 1 11 21 31 41 51 61 71 81 91,输出 20.00%、20.00%、20.00%、40.00%。

思路

三个右端点 18/35/6018/35/60 把年龄切成四段:年龄严格大于几个右端点,就属于第几段,据此累加四个计数器。 统计完后逐段输出 该段人数 * 100 / n,保留两位小数并加 %,复杂度 O(n)O(n)。

参考代码

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 19:05
# update_at: 2026-09-29 19:05

import sys

# 四个年龄段的右端点(19-35、36-60、61 以上),0-18 单独算:年龄 ≤ 右端点的第一个桶
BOUNDS = [18, 35, 60]


def bucket(age: int) -> int:
    """返回年龄所属桶:0=0-18,1=19-35,2=36-60,3=61 以上。"""
    return sum(age > bound for bound in BOUNDS)  # 越过几个右端点就是第几桶


def solve() -> None:
    data = iter(map(int, sys.stdin.buffer.read().split()))
    n = next(data)

    counts = [0, 0, 0, 0]
    for _ in range(n):
        age = next(data)
        counts[bucket(age)] += 1

    print('\n'.join(f'{count * 100 / n:.2f}%' for count in counts))


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 01:15
 * update_at: 2026-10-05 01:15
 */
// main.cpp:按 0-18、19-35、36-60、61 以上四段统计患病人数百分比。
#include <cstdio>

typedef long long ll;

const int MAXN = 105;
ll age[MAXN]; // age[i] 表示第 i 个病人的年龄
ll cnt[4];    // cnt[b] 表示第 b 段的人数:0=0-18,1=19-35,2=36-60,3=61 以上

int main() {
    ll n; // 病人总数
    if (scanf("%lld", &n) != 1) {
        return 0;
    }
    for (ll i = 1; i <= n; i++) {
        scanf("%lld", &age[i]);
    }

    // 四个年龄段由三个右端点 18、35、60 划分:
    // 年龄严格越过几个右端点,就属于第几段
    for (ll i = 1; i <= n; i++) {
        ll bucket = 0; // 当前年龄所属的年龄段编号
        if (age[i] > 18) {
            bucket++;
        }
        if (age[i] > 35) {
            bucket++;
        }
        if (age[i] > 60) {
            bucket++;
        }
        cnt[bucket]++;
    }

    for (ll b = 0; b < 4; b++) {
        double ratio = cnt[b] * 100.0 / n; // 该段人数占总人数的百分比
        printf("%.2f%%\n", ratio);
    }
    return 0;
}