# 第6课编程题(教师版) ## 本课知识点覆盖表 | 核心知识点 | GESP等级 | 对应课堂题 | |---|---|---| | 外层控制行、内层控制列、实心矩形 | 二级必考 | 课堂1 | | 行列关系、左下与右下三角形 | 二级必考 | 课堂2 | | 空格数与星号数、等腰三角形与菱形 | 二级必考 | 课堂3 | | 双层循环的非图形应用、行列组合 | 二级 | 课堂4 | ## 一、课堂练习(4题) ### 课堂1:实心与空心矩形【适中】 **题目描述:** 输入行数 `n`、列数 `m` 和模式 `type`。当 `type=1` 时打印实心矩形;当 `type=2` 时打印空心矩形。 **输入格式:** 依次输入行数、列数和图形模式。 **输出格式:** 用星号打印指定矩形。 **数据范围:** `1≤n,m≤30`,`type` 为 1 或 2。 **输入样例:** ```text 3 5 2 ``` **输出样例:** ```text ***** * * ***** ``` **解题思路:** 双层循环枚举行列。实心模式总输出星号;空心模式只在首尾行或首尾列输出星号。 **参考代码:** ```cpp #include using namespace std; int main() { int n, m, type; cin >> n >> m >> type; for (int i = 1; i <= n; i++) { for (int j = 1; j <= m; j++) { if (type == 1 || i == 1 || i == n || j == 1 || j == m) cout << "*"; else cout << " "; } cout << "\n"; } return 0; } ``` **易错提醒:** 每打印完一行才换行;`n=1` 或 `m=1` 时所有位置都在边界上。 ### 课堂2:四种直角三角形【适中】 **题目描述:** 输入 `n` 和类型 `type`,打印边长为 `n` 的直角三角形:1 左下、2 右下、3 左上、4 右上。 **输入格式:** 输入三角形边长和图形类型。 **输出格式:** 指定方向的星号三角形。 **数据范围:** `1≤n≤30`,`1≤type≤4`。 **输入样例:** ```text 4 2 ``` **输出样例:** ```text * ** *** **** ``` **解题思路:** 第 `i` 行星号数量为 `i` 或 `n-i+1`;右对齐时先输出相应数量空格。 **参考代码:** ```cpp #include using namespace std; int main() { int n, type; cin >> n >> type; for (int i = 1; i <= n; i++) { int stars = (type == 1 || type == 2) ? i : n - i + 1; int spaces = (type == 2 || type == 4) ? n - stars : 0; for (int j = 1; j <= spaces; j++) cout << " "; for (int j = 1; j <= stars; j++) cout << "*"; cout << "\n"; } return 0; } ``` **易错提醒:** 右对齐不是改变星号数量,而是在星号前补空格。 ### 课堂3:等腰三角形与菱形【适中】 **题目描述:** 输入 `n` 和模式 `type`。模式 1 打印高为 `n` 的实心等腰三角形;模式 2 打印上下高度均为 `n`、中间行不重复的菱形。 **输入格式:** 输入图形高度和图形模式。 **输出格式:** 指定图形。 **数据范围:** `1≤n≤20`。 **输入样例:** ```text 3 2 ``` **输出样例:** ```text * *** ***** *** * ``` **解题思路:** 上半部分第 `i` 行有 `n-i` 个空格和 `2i-1` 个星号;菱形下半部分按相反规律输出。 **参考代码:** ```cpp #include using namespace std; void printRow(int spaces, int stars) { for (int j = 0; j < spaces; j++) cout << " "; for (int j = 0; j < stars; j++) cout << "*"; cout << "\n"; } int main() { int n, type; cin >> n >> type; for (int i = 1; i <= n; i++) printRow(n - i, 2 * i - 1); if (type == 2) { for (int i = n - 1; i >= 1; i--) printRow(n - i, 2 * i - 1); } return 0; } ``` **易错提醒:** 菱形下半部分从 `n-1` 开始,避免中间最长行重复。 ### 课堂4:九九乘法表【适中】 **题目描述:** 输入 `n`,打印 `1~n` 的下三角乘法表。第 `i` 行输出 `1×i` 到 `i×i`。 **输入格式:** 输入乘法表的最大因数。 **输出格式:** 下三角乘法表,每项格式为 `j*i=积`,项之间一个空格。 **数据范围:** `1≤n≤9`。 **输入样例:** ```text 3 ``` **输出样例:** ```text 1*1=1 1*2=2 2*2=4 1*3=3 2*3=6 3*3=9 ``` **解题思路:** 外层 `i` 控制行和第二个因数,内层 `j` 从 1 走到 `i`。 **参考代码:** ```cpp #include using namespace std; int main() { int n; cin >> n; for (int i = 1; i <= n; i++) { for (int j = 1; j <= i; j++) { if (j > 1) cout << " "; cout << j << "*" << i << "=" << j * i; } cout << "\n"; } return 0; } ``` **易错提醒:** 内层上界是当前行号 `i`,不是固定的 `n`。 ## 二、课后作业(3题) ### 课后1:实心正方形【简单】 **题目描述:** 输入 `n`,打印 `n×n` 的星号正方形。 **输入格式:** 输入正方形的边长。 **输出格式:** 实心正方形。 **数据范围:** `1≤n≤20`。 **输入样例:** ```text 3 ``` **输出样例:** ```text *** *** *** ``` **解题思路:** 外层循环 `n` 行,内层每行输出 `n` 个星号。 **参考代码:** ```cpp #include using namespace std; int main() { int n; cin >> n; for (int i = 1; i <= n; i++) { for (int j = 1; j <= n; j++) cout << "*"; cout << "\n"; } return 0; } ``` **易错提醒:** 换行语句应放在内层循环结束之后。 ### 课后2:左下数字三角形【简单】 **题目描述:** 输入 `n`,第 `i` 行输出 `i` 个数字 `i`。 **输入格式:** 输入数字三角形的行数。 **输出格式:** 数字三角形。 **数据范围:** `1≤n≤9`。 **输入样例:** ```text 4 ``` **输出样例:** ```text 1 22 333 4444 ``` **解题思路:** 外层行号决定输出数字,也决定内层循环次数。 **参考代码:** ```cpp #include using namespace std; int main() { int n; cin >> n; for (int i = 1; i <= n; i++) { for (int j = 1; j <= i; j++) cout << i; cout << "\n"; } return 0; } ``` **易错提醒:** 输出的是行号 `i`,不是列号 `j`。 ### 课后3:棋盘格【简单】 **题目描述:** 输入 `n` 和 `m`,打印棋盘格;行列编号之和为偶数输出 `#`,否则输出 `.`。 **输入格式:** 输入棋盘格的行数和列数。 **输出格式:** `n` 行 `m` 列棋盘格。 **数据范围:** `1≤n,m≤30`。 **输入样例:** ```text 3 4 ``` **输出样例:** ```text #.#. .#.# #.#. ``` **解题思路:** 双层循环枚举位置,根据 `(i+j)%2` 决定字符。 **参考代码:** ```cpp #include using namespace std; int main() { int n, m; cin >> n >> m; for (int i = 1; i <= n; i++) { for (int j = 1; j <= m; j++) cout << ((i + j) % 2 == 0 ? '#' : '.'); cout << "\n"; } return 0; } ``` **易错提醒:** 行列从 1 开始时,左上角的和为 2,应输出 `#`。 ## 三、扩展练习(7题) ### 扩展1:坐标表【基础综合】 **题目描述:** 输入 `n m`,按行输出所有坐标 `(i,j)`。 **输入格式:** 输入坐标表的行数和列数。 **输出格式:** 每行输出一行坐标,坐标之间一个空格。 **数据范围:** `1≤n,m≤10`。 **输入样例:** ```text 2 2 ``` **输出样例:** ```text (1,1) (1,2) (2,1) (2,2) ``` **解题思路:** 外层决定第一坐标,内层决定第二坐标。 **参考代码:** ```cpp #include using namespace std; int main() { int n, m; cin >> n >> m; for (int i = 1; i <= n; i++) { for (int j = 1; j <= m; j++) { if (j > 1) cout << " "; cout << "(" << i << "," << j << ")"; } cout << "\n"; } return 0; } ``` **易错提醒:** 同一行坐标之间输出空格,行末不必输出多余空格。 ### 扩展2:回文数字三角形【中等】 **题目描述:** 输入 `n`,第 `i` 行依次输出 `1~i~1`。 **输入格式:** 输入回文数字三角形的行数。 **输出格式:** 回文数字三角形。 **数据范围:** `1≤n≤9`。 **输入样例:** ```text 4 ``` **输出样例:** ```text 1 121 12321 1234321 ``` **解题思路:** 每行使用两个内层循环:第一个递增到 `i`,第二个从 `i-1` 递减到 1。 **参考代码:** ```cpp #include using namespace std; int main() { int n; cin >> n; for (int i = 1; i <= n; i++) { for (int j = 1; j <= i; j++) cout << j; for (int j = i - 1; j >= 1; j--) cout << j; cout << "\n"; } return 0; } ``` **易错提醒:** 下降部分从 `i-1` 开始,避免中间数字重复。 ### 扩展3:空心直角三角形【中等】 **题目描述:** 输入 `n`,打印左下空心直角三角形。 **输入格式:** 输入空心直角三角形的边长。 **输出格式:** 指定图形。 **数据范围:** `2≤n≤30`。 **输入样例:** ```text 5 ``` **输出样例:** ```text * ** * * * * ***** ``` **解题思路:** 第 `i` 行有 `i` 个位置;首列、斜边 `j=i`、底边 `i=n` 输出星号。 **参考代码:** ```cpp #include using namespace std; int main() { int n; cin >> n; for (int i = 1; i <= n; i++) { for (int j = 1; j <= i; j++) { if (j == 1 || j == i || i == n) cout << "*"; else cout << " "; } cout << "\n"; } return 0; } ``` **易错提醒:** 第二行两个位置都属于边界,所以会输出两个星号。 ### 扩展4:字母方阵【中等】 **题目描述:** 输入 `n`,第 `i` 行第 `j` 列输出从 `A` 开始向后平移 `i+j-2` 位的字母,超过 `Z` 循环。 **输入格式:** 输入字母方阵的边长。 **输出格式:** `n×n` 字母方阵。 **数据范围:** `1≤n≤20`。 **输入样例:** ```text 3 ``` **输出样例:** ```text ABC BCD CDE ``` **解题思路:** 用行列共同决定平移量,字符公式为 `'A'+(i+j-2)%26`。 **参考代码:** ```cpp #include using namespace std; int main() { int n; cin >> n; for (int i = 1; i <= n; i++) { for (int j = 1; j <= n; j++) cout << (char)('A' + (i + j - 2) % 26); cout << "\n"; } return 0; } ``` **易错提醒:** ASCII 平移后要转换为字符;取模保证不会越过 `Z`。 ### 扩展5:X形图案【中等】 **题目描述:** 输入奇数 `n`,打印 `n×n` 方阵,两条对角线输出 `*`,其他位置输出 `.`。 **输入格式:** 输入一个奇数,表示方阵的边长。 **输出格式:** X 形图案。 **数据范围:** `1≤n≤31`,`n` 为奇数。 **输入样例:** ```text 5 ``` **输出样例:** ```text *...* .*.*. ..*.. .*.*. *...* ``` **解题思路:** 主对角线满足 `i=j`,副对角线满足 `i+j=n+1`。 **参考代码:** ```cpp #include using namespace std; int main() { int n; cin >> n; for (int i = 1; i <= n; i++) { for (int j = 1; j <= n; j++) { if (i == j || i + j == n + 1) cout << "*"; else cout << "."; } cout << "\n"; } return 0; } ``` **易错提醒:** 副对角线条件使用 `n+1`,因为行列编号从 1 开始。 ### 扩展6:空心菱形【略难】 **题目描述:** 输入 `n`,打印总高度为 `2n-1` 的空心菱形。 **输入格式:** 输入菱形上半部分的高度。 **输出格式:** 空心菱形。 **数据范围:** `1≤n≤20`。 **输入样例:** ```text 3 ``` **输出样例:** ```text * * * * * * * * ``` **解题思路:** 把每一行映射为到中间行的层数 `level`;输出前导空格、左边星号,宽度大于 1 时再输出内部空格和右边星号。 **参考代码:** ```cpp #include #include using namespace std; int main() { int n; cin >> n; for (int row = 1; row <= 2 * n - 1; row++) { int level = n - abs(n - row); int outer = n - level; int inner = 2 * level - 3; for (int j = 0; j < outer; j++) cout << " "; cout << "*"; if (inner >= 0) { for (int j = 0; j < inner; j++) cout << " "; cout << "*"; } cout << "\n"; } return 0; } ``` **易错提醒:** 顶点和底点只有一个星号,此时不能输出第二个星号。 ### 扩展7:组合沙漏【略难】 **题目描述:** 输入 `n`,打印由星号组成的实心沙漏。第一行有 `2n-1` 个星号,逐行减少两个到 1,再逐行增加两个;中间行只输出一次。 **输入格式:** 输入沙漏上半部分的高度。 **输出格式:** 实心沙漏。 **数据范围:** `1≤n≤20`。 **输入样例:** ```text 3 ``` **输出样例:** ```text ***** *** * *** ***** ``` **解题思路:** 上半部分第 `i` 行输出 `i-1` 个空格和 `2(n-i)+1` 个星号;下半部分反向恢复。 **参考代码:** ```cpp #include using namespace std; void printRow(int spaces, int stars) { for (int j = 0; j < spaces; j++) cout << " "; for (int j = 0; j < stars; j++) cout << "*"; cout << "\n"; } int main() { int n; cin >> n; for (int i = 1; i <= n; i++) printRow(i - 1, 2 * (n - i) + 1); for (int i = n - 1; i >= 1; i--) printRow(i - 1, 2 * (n - i) + 1); return 0; } ``` **易错提醒:** 下半部分从 `n-1` 开始,避免最窄的中间行重复。