题解:洛谷 P5730 显示屏
【题目来源】
【题目描述】
液晶屏上,每个阿拉伯数字都是可以显示成 \(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
【核心思想】
-
问题分析:给定一个长度为 \(n\)(\(n \le 100\))的数字串,需要将每个数字按 \(3 \times 5\) 的点阵(字符
X和.组成)显示出来,每个数字之间用一列.分隔。最终输出 5 行字符串。本质是字符画拼接问题,关键是存储每个数字的 5 行点阵模板,然后按顺序拼接。 -
算法选择:
- 模板存储 + 逐行拼接:使用一个三维字符串数组
a[10][5]存储 0~9 每个数字的 5 行点阵(每行 3 个字符)。读取数字串后,对于每一行row(0~4),遍历数字串的每个数字,将其对应的a[digit][row]追加到输出行s[row]中,并在数字之间(除最后一个外)追加一个.作为列间隔。最后输出 5 行。 - 复杂度:\(O(n)\),因为每个数字只需常数次拼接操作。
- 模板存储 + 逐行拼接:使用一个三维字符串数组
-
关键步骤:
- 初始化模板:手动初始化 10 个数字的 5 行点阵(每个点阵为 3 字符字符串)。
- 读入与拼接:读入 \(n\) 和数字串
str。初始化 5 个空字符串s[0..4]。遍历str中的每个字符ch,将其转换为数字t,然后将a[t][j]追加到s[j](\(j=0..4\)),若不是最后一个数字,再追加一个.。 - 输出:按行输出
s[0]到s[4]。
-
时间/空间复杂度:
- 时间复杂度:\(O(5n)\),即 \(O(n)\)。
- 空间复杂度:\(O(5n)\),存储输出行。
-
模拟与字符串拼接:
- 模板复用:每个数字的 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
浙公网安备 33010602011771号