Files
project1/第05课-嵌套循环与图形打印/编程题-教师版.md
2026-07-02 16:54:05 +08:00

13 KiB
Raw Blame History

第6课编程题教师版

本课知识点覆盖表

核心知识点 GESP等级 对应课堂题
外层控制行、内层控制列、实心矩形 二级必考 课堂1
行列关系、左下与右下三角形 二级必考 课堂2
空格数与星号数、等腰三角形与菱形 二级必考 课堂3
双层循环的非图形应用、行列组合 二级 课堂4

一、课堂练习4题

课堂1实心与空心矩形【适中】

题目描述: 输入行数 n、列数 m 和模式 type。当 type=1 时打印实心矩形;当 type=2 时打印空心矩形。

输入格式: 依次输入行数、列数和图形模式。

输出格式: 用星号打印指定矩形。

数据范围: 1≤n,m≤30type 为 1 或 2。

输入样例:

3 5 2

输出样例:

*****
*   *
*****

解题思路: 双层循环枚举行列。实心模式总输出星号;空心模式只在首尾行或首尾列输出星号。

参考代码:

#include <iostream>
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=1m=1 时所有位置都在边界上。

课堂2四种直角三角形【适中】

题目描述: 输入 n 和类型 type,打印边长为 n 的直角三角形1 左下、2 右下、3 左上、4 右上。

输入格式: 输入三角形边长和图形类型。

输出格式: 指定方向的星号三角形。

数据范围: 1≤n≤301≤type≤4

输入样例:

4 2

输出样例:

   *
  **
 ***
****

解题思路:i 行星号数量为 in-i+1;右对齐时先输出相应数量空格。

参考代码:

#include <iostream>
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

输入样例:

3 2

输出样例:

  *
 ***
*****
 ***
  *

解题思路: 上半部分第 i 行有 n-i 个空格和 2i-1 个星号;菱形下半部分按相反规律输出。

参考代码:

#include <iostream>
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,打印 1n 的下三角乘法表。第 i 行输出 1×ii×i

输入格式: 输入乘法表的最大因数。

输出格式: 下三角乘法表,每项格式为 j*i=积,项之间一个空格。

数据范围: 1≤n≤9

输入样例:

3

输出样例:

1*1=1
1*2=2 2*2=4
1*3=3 2*3=6 3*3=9

解题思路: 外层 i 控制行和第二个因数,内层 j 从 1 走到 i

参考代码:

#include <iostream>
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

输入样例:

3

输出样例:

***
***
***

解题思路: 外层循环 n 行,内层每行输出 n 个星号。

参考代码:

#include <iostream>
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

输入样例:

4

输出样例:

1
22
333
4444

解题思路: 外层行号决定输出数字,也决定内层循环次数。

参考代码:

#include <iostream>
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棋盘格【简单】

题目描述: 输入 nm,打印棋盘格;行列编号之和为偶数输出 #,否则输出 .

输入格式: 输入棋盘格的行数和列数。

输出格式: nm 列棋盘格。

数据范围: 1≤n,m≤30

输入样例:

3 4

输出样例:

#.#.
.#.#
#.#.

解题思路: 双层循环枚举位置,根据 (i+j)%2 决定字符。

参考代码:

#include <iostream>
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

输入样例:

2 2

输出样例:

(1,1) (1,2)
(2,1) (2,2)

解题思路: 外层决定第一坐标,内层决定第二坐标。

参考代码:

#include <iostream>
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 行依次输出 1i1

输入格式: 输入回文数字三角形的行数。

输出格式: 回文数字三角形。

数据范围: 1≤n≤9

输入样例:

4

输出样例:

1
121
12321
1234321

解题思路: 每行使用两个内层循环:第一个递增到 i,第二个从 i-1 递减到 1。

参考代码:

#include <iostream>
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

输入样例:

5

输出样例:

*
**
* *
*  *
*****

解题思路:i 行有 i 个位置;首列、斜边 j=i、底边 i=n 输出星号。

参考代码:

#include <iostream>
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

输入样例:

3

输出样例:

ABC
BCD
CDE

解题思路: 用行列共同决定平移量,字符公式为 'A'+(i+j-2)%26

参考代码:

#include <iostream>
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

扩展5X形图案【中等】

题目描述: 输入奇数 n,打印 n×n 方阵,两条对角线输出 *,其他位置输出 .

输入格式: 输入一个奇数,表示方阵的边长。

输出格式: X 形图案。

数据范围: 1≤n≤31n 为奇数。

输入样例:

5

输出样例:

*...*
.*.*.
..*..
.*.*.
*...*

解题思路: 主对角线满足 i=j,副对角线满足 i+j=n+1

参考代码:

#include <iostream>
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

输入样例:

3

输出样例:

  *
 * *
*   *
 * *
  *

解题思路: 把每一行映射为到中间行的层数 level;输出前导空格、左边星号,宽度大于 1 时再输出内部空格和右边星号。

参考代码:

#include <iostream>
#include <cmath>
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

输入样例:

3

输出样例:

*****
 ***
  *
 ***
*****

解题思路: 上半部分第 i 行输出 i-1 个空格和 2(n-i)+1 个星号;下半部分反向恢复。

参考代码:

#include <iostream>
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 开始,避免最窄的中间行重复。