题解:洛谷 P5730 显示屏

【题目来源】

洛谷:P5730 【深基5.例10】显示屏 - 洛谷

【题目描述】

液晶屏上,每个阿拉伯数字都是可以显示成 \(3\times 5\) 的点阵的(其中 X 表示亮点,. 表示暗点)。现在给出数字位数(不超过 \(100\))和一串数字,要求输出这些数字在显示屏上的效果。数字的显示方式如同样例输出,注意每个数字之间都有一列间隔。

【输入】

第一行输入一个正整数 \(n\),表示数字的位数。

第二行输入一个长度为 \(n\) 的自然数。

【输出】

输出五行,表示显示屏上的数字。

【输入样例】

10
0123456789

【输出样例】

XXX...X.XXX.XXX.X.X.XXX.XXX.XXX.XXX.XXX
X.X...X...X...X.X.X.X...X.....X.X.X.X.X
X.X...X.XXX.XXX.XXX.XXX.XXX...X.XXX.XXX
X.X...X.X.....X...X...X.X.X...X.X.X...X
XXX...X.XXX.XXX...X.XXX.XXX...X.XXX.XXX

【核心思想】

  1. 问题分析:给定一个长度为 \(n\)\(n \le 100\))的数字串,需要将每个数字按 \(3 \times 5\) 的点阵(字符 X. 组成)显示出来,每个数字之间用一列 . 分隔。最终输出 5 行字符串。本质是字符画拼接问题,关键是存储每个数字的 5 行点阵模板,然后按顺序拼接。

  2. 算法选择

    • 模板存储 + 逐行拼接:使用一个三维字符串数组 a[10][5] 存储 0~9 每个数字的 5 行点阵(每行 3 个字符)。读取数字串后,对于每一行 row(0~4),遍历数字串的每个数字,将其对应的 a[digit][row] 追加到输出行 s[row] 中,并在数字之间(除最后一个外)追加一个 . 作为列间隔。最后输出 5 行。
    • 复杂度\(O(n)\),因为每个数字只需常数次拼接操作。
  3. 关键步骤

    • 初始化模板:手动初始化 10 个数字的 5 行点阵(每个点阵为 3 字符字符串)。
    • 读入与拼接:读入 \(n\) 和数字串 str。初始化 5 个空字符串 s[0..4]。遍历 str 中的每个字符 ch,将其转换为数字 t,然后将 a[t][j] 追加到 s[j]\(j=0..4\)),若不是最后一个数字,再追加一个 .
    • 输出:按行输出 s[0]s[4]
  4. 时间/空间复杂度

    • 时间复杂度:\(O(5n)\),即 \(O(n)\)
    • 空间复杂度:\(O(5n)\),存储输出行。
  5. 模拟与字符串拼接

    • 模板复用:每个数字的 5 行点阵是固定的,预先存储可以避免在代码中重复定义。
    • 逐行构建:由于输出是按行组织的,且每个数字的每一行需要横向拼接,因此采用“按数字遍历,逐行追加”的方式最自然。
    • 分隔符控制:在数字之间添加 . 分隔,但最后一个数字后不加,因此用条件 if (i != n-1) 控制。
    • 适用场景:这类“字符画/点阵显示”问题常见于模拟题,核心是准确存储模板并按顺序拼接。

【算法标签】

普及- #模拟

【代码详解】

#include <bits/stdc++.h>  // 包含标准库头文件(万能头文件)
using namespace std;      // 使用标准命名空间

int n;                   // 定义变量:数字的位数
string s[5];             // 定义数组:存储最终输出的5行字符串
string a[10][5];         // 定义二维数组:存储0-9每个数字的5行点阵表示
string str;              // 定义变量:输入的数字字符串

int main()
{
    // 初始化数字0的点阵表示
    a[0][0] = "XXX";
    a[0][1] = "X.X";
    a[0][2] = "X.X";
    a[0][3] = "X.X";
    a[0][4] = "XXX";

    // 初始化数字1的点阵表示
    a[1][0] = "..X";
    a[1][1] = "..X";
    a[1][2] = "..X";
    a[1][3] = "..X";
    a[1][4] = "..X";

    // 初始化数字2的点阵表示
    a[2][0] = "XXX";
    a[2][1] = "..X";
    a[2][2] = "XXX";
    a[2][3] = "X..";
    a[2][4] = "XXX";

    // 初始化数字3的点阵表示
    a[3][0] = "XXX";
    a[3][1] = "..X";
    a[3][2] = "XXX";
    a[3][3] = "..X";
    a[3][4] = "XXX";

    // 初始化数字4的点阵表示
    a[4][0] = "X.X";
    a[4][1] = "X.X";
    a[4][2] = "XXX";
    a[4][3] = "..X";
    a[4][4] = "..X";

    // 初始化数字5的点阵表示
    a[5][0] = "XXX";
    a[5][1] = "X..";
    a[5][2] = "XXX";
    a[5][3] = "..X";
    a[5][4] = "XXX";

    // 初始化数字6的点阵表示
    a[6][0] = "XXX";
    a[6][1] = "X..";
    a[6][2] = "XXX";
    a[6][3] = "X.X";
    a[6][4] = "XXX";

    // 初始化数字7的点阵表示
    a[7][0] = "XXX";
    a[7][1] = "..X";
    a[7][2] = "..X";
    a[7][3] = "..X";
    a[7][4] = "..X";

    // 初始化数字8的点阵表示
    a[8][0] = "XXX";
    a[8][1] = "X.X";
    a[8][2] = "XXX";
    a[8][3] = "X.X";
    a[8][4] = "XXX";

    // 初始化数字9的点阵表示
    a[9][0] = "XXX";
    a[9][1] = "X.X";
    a[9][2] = "XXX";
    a[9][3] = "..X";
    a[9][4] = "XXX";

    // 输入数字位数和数字字符串
    cin >> n >> str;

    // 构建点阵输出
    for (int i = 0; i < n; i++)
    {
        int t = str[i] - '0';  // 将字符数字转换为整型数字

        // 将当前数字的点阵拼接到输出字符串中
        for (int j = 0; j < 5; j++)
        {
            s[j] += a[t][j];    // 拼接当前数字的点阵行

            // 如果不是最后一个数字,添加点分隔符
            if (i != n - 1)
                s[j] += ".";
        }
    }

    // 输出最终的点阵结果
    for (int i = 0; i < 5; i++)
        cout << s[i] << endl;

    return 0;                   // 程序正常结束
}

【运行结果】

5
12345
..X.XXX.XXX.X.X.XXX
..X...X...X.X.X.X..
..X.XXX.XXX.XXX.XXX
..X.X.....X...X...X
..X.XXX.XXX...X.XXX
posted @ 2026-08-30 09:19  团爸讲算法  阅读(15)  评论(0)    收藏  举报