循环嵌套加字符打印
2026-09-18 19:29:38
发布于:湖北
16阅读
0回复
0点赞
题目解析:字符变换(8×16 画布填字符)
一、题意梳理
- 画布共 8 行 16 列 = 128 个格子,按"从上到下、从左到右"编号 1~128(第 1 行是 1~16,第 8 行是 113~128)。
- 初始每格都是
*;读入三个正整数 ,把编号等于该数的格子替换成该数对应的 ASCII 字符(如 48→'0'、65→'A'、97→'a')。 - 最后按行输出整个画布(每行 16 个字符,行末换行,无多余空格)。
二、考查知识点
- ASCII 码与强制类型转换:
(char)48='0'、(char)65='A'、(char)97='a'。记住三段连续区间:48~57 是0`9`,6590 是A`Z`,97122 是a~z。 - 一维编号 ↔ 二维坐标互化(网格题基本功):编号 (从 1 开始)对应
- 二重循环遍历网格与换行控制。
三、思路与代码
写法一:计数器模拟(最直观,边遍历边对号)
按行、列顺序遍历 128 个格子,用计数器 p 记录当前编号,命中三个数之一就输出对应字符,否则输出 *。
#include <iostream>
using namespace std;
int main(){
int a, b, c, p = 0;
cin >> a >> b >> c;
for(int i = 1; i <= 8; ++i){ // 行
for(int j = 1; j <= 16; ++j){ // 列
++p; // 当前格子编号
if(p == a) cout << (char)a;
else if(p == b) cout << (char)b;
else if(p == c) cout << (char)c;
else cout << '*';
}
cout << '\n'; // 每行结束换行
}
return 0;
}
写法二:坐标定位法(先建画布再"点穴")
先用 * 填满 8×16 字符数组,再把三个编号换算成行列并填入字符,最后整体输出。此法更通用(格子数多、替换次数多时也好扩展)。
#include <iostream>
using namespace std;
int main(){
char g[8][16];
for(int i = 0; i < 8; ++i)
for(int j = 0; j < 16; ++j)
g[i][j] = '*';
for(int t = 0; t < 3; ++t){
int x; cin >> x;
int r = (x - 1) / 16, c = (x - 1) % 16; // 注意先减 1
g[r][c] = (char)x;
}
for(int i = 0; i < 8; ++i){
for(int j = 0; j < 16; ++j)
cout << g[i][j];
cout << '\n';
}
return 0;
}
四、样例验证(输入 48 / 65 / 97)
| 编号 x | (x−1)/16 → 行(0起) | (x−1)%16 → 列(0起) | 字符 | 位置 |
|---|---|---|---|---|
| 48 | 47/16=2 → 第 3 行 | 47%16=15 → 第 16 列 | '0' |
第 3 行行尾 |
| 65 | 64/16=4 → 第 5 行 | 0 → 第 1 列 | 'A' |
第 5 行行首 |
| 97 | 96/16=6 → 第 7 行 | 0 → 第 1 列 | 'a' |
第 7 行行首 |
与样例输出完全一致:第 3 行末尾是 0,第 5 行开头是 A,第 7 行开头是 a,其余全 *。✓
五、易错点提醒
- 编号从 1 开始:换算坐标必须先
x-1,否则 16 的倍数编号(如 48、64)会错行错列。 - 每行恰好 16 个字符且行末换行:多打空格或少换行都会判格式错误。
- 输出的是字符不是数字:必须
(char)x强制转换;直接cout << x会输出 48 而不是0。 - 三个数可能落在同一行甚至理论上重复:写法一的
if-else链与写法二的覆盖赋值都能自然处理,无需特判。 - 数据范围保证输入落在 4857、6590、97~122(即可打印的数字/字母),无需额外合法性判断。
这道题是 GESP 二级里"网格 + ASCII"的典型送分题,核心只有一句话——把一维编号用 (x-1)/列数 和 (x-1)%列数 还原成二维坐标。把这个公式练熟,以后遇到任意 画布、蛇形填数、螺旋矩阵等题都能直接套用。
这里空空如也



有帮助,赞一个