[USACO03FEB] 垂直柱状图 Vertical Histogram

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

统计 A 到 Z 的出现次数,从最高层向下逐行输出星号,并用 rstrip 删除行尾多余空格。

OJ: luogu

题目 ID: P1598

难度:普及-

标签:字符串计数模拟python

日期: 2026-07-15 21:01

题意

读入四行字符,统计 AZ 每个大写字母出现的次数,并按样例格式输出垂直柱状图。每一行末尾不能有多余空格。

思路

先统计 26 个大写字母的出现次数。设最高次数是 max_height,柱状图就从第 max_height 层往第 1 层输出。

对于某一层 level

  • 如果某个字母的次数 >= level,这一列输出 *
  • 否则输出空格。

列与列之间固定用一个空格隔开。整行生成后,用 rstrip() 删除右侧多余空格,避免违反格式要求。最后输出字母行:

text
A B C ... Z

这题是计数和格式化输出练习,不创建 brute.py

Python 知识

  • /home/rainboy/mycode/hugo-blog/content/program_language/python/collections_toolkit.mdCounter 可以统计字符出现次数。
  • /home/rainboy/mycode/hugo-blog/content/program_language/python/input_output_and_strings.md" ".join(row) 拼接一行输出。
  • chr(ord("A") + i) 生成第 i 个大写字母。
  • rstrip() 删除行尾空格,保留中间空格。

代码

python
from collections import Counter


counter = Counter()

for _ in range(4):
    line = input()
    for ch in line:
        if "A" <= ch <= "Z":
            counter[ch] += 1

heights = [counter[chr(ord("A") + i)] for i in range(26)]
max_height = max(heights)

for level in range(max_height, 0, -1):
    row = []
    for height in heights:
        if height >= level:
            row.append("*")
        else:
            row.append(" ")
    print(" ".join(row).rstrip())

print(" ".join(chr(ord("A") + i) for i in range(26)))
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-07-27 00:00
 * update_at: 2026-07-27 00:00
 */

#include <bits/stdc++.h>
using namespace std;

int cnt[26]; // cnt[i] 记录大写字母 'A'+i 的出现次数
char line[105];

int main() {
    // 读入 4 行文本,统计大写字母
    for (int k = 1; k <= 4; k++) {
        cin.getline(line, 105);
        int len = strlen(line);
        for (int i = 0; i < len; i++) {
            if (line[i] >= 'A' && line[i] <= 'Z')
                cnt[line[i] - 'A']++;
        }
    }

    // 找最大高度
    int maxh = 0;
    for (int i = 0; i < 26; i++)
        if (cnt[i] > maxh) maxh = cnt[i];

    // 从最高层向下输出柱状图
    for (int h = maxh; h >= 1; h--) {
        for (int i = 0; i < 26; i++) {
            if (cnt[i] >= h) cout << "*";
            else cout << " ";
            if (i != 25) cout << " ";
        }
        cout << "\n";
    }

    // 输出字母行
    for (int i = 0; i < 26; i++) {
        cout << char('A' + i);
        if (i != 25) cout << " ";
    }
    return 0;
}

Pythonic 写法

Counter 统计字母,按高度逐行输出柱状图:

python
from collections import Counter

counter = Counter(ch for _ in range(4) for ch in input() if "A" <= ch <= "Z")
letters = [chr(ord("A") + i) for i in range(26)]
heights = [counter[ch] for ch in letters]
for level in range(max(heights), 0, -1):
    print(" ".join("*" if h >= level else " " for h in heights).rstrip())
print(" ".join(letters))

复杂度

输入总长度最多约 400,统计和输出都很小。若用总字符数 n、最高柱高 h 表示,时间复杂度是 O(n+26h)O(n + 26h),空间复杂度是 O(1)O(1)

总结

垂直柱状图的关键是“按高度从上到下输出”。生成含空格的格式化行后,最后统一 rstrip() 去掉行尾多余空格。