CCF GESP C++编程题的详细题解

CCF GESP C++编程题的详细题解:


题目一:B4037 [GESP202409 ] 小杨的 N 字矩阵

题目链接: https://www.luogu.com.cn/problem/B4037

题目描述

小杨想要构造一个 \(n \times n\) 的 N 字矩阵(\(n\) 为奇数),这个矩阵的从左上角到右下角的对角线、第 \(1\) 列和第 \(n\) 列都是半角加号 +,其余都是半角减号 -。例如,一个 \(n=5\) 的 N 字矩阵如下:

+---+
++--+
+-+-+
+--++
+---+

输入格式

输入只有一行包含一个正整数 \(n\)

输出格式

输出对应的 N 字矩阵。

输入输出样例

输入 #1

5

输出 #1

+---+
++--+
+-+-+
+--++
+---+

数据规模与约定

对全部的测试数据,保证 \(3 \le n \le 49\)\(n\) 是奇数。

解题思路

这是一个典型的二维矩阵构造问题,需要判断每个位置应该填充什么字符。对于第 \(i\) 行第 \(j\) 列(从0开始计数):

  • \(1\) 列(\(j=0\))或第 \(n\) 列(\(j=n-1\)):输出 +
  • 主对角线(\(i=j\)):输出 +
  • 其他位置:输出 -

C++ 代码实现

#include <iostream>
using namespace std;

int main() {
    int n;
    cin >> n;
    
    for (int i = 0; i < n; i++) {      // 遍历每一行
        for (int j = 0; j < n; j++) {  // 遍历每一列
            // 第1列、第n列或主对角线
            if (j == 0 || j == n - 1 || i == j) {
                cout << "+";
            } else {
                cout << "-";
            }
        }
        cout << endl;  // 每行结束换行
    }
    
    return 0;
}

关键点:

  1. 使用双重循环遍历矩阵的每个位置
  2. 判断条件:j == 0(第1列)、j == n-1(第n列)、i == j(主对角线)
  3. 注意数组下标从0开始,所以第1列对应 j=0,第n列对应 j=n-1
  4. 每行输出结束后必须换行

题目二:B3924 [GESP202312 ] 小杨的 H 字矩阵

题目链接: https://www.luogu.com.cn/problem/B3924

题目描述

小杨想要构造一个 \(n \times n\) 的 H 字矩阵(\(n\) 为奇数),具体来说,这个矩阵共有 \(n\) 行,每行 \(n\) 个字符,其中最左列、最右列都是 |,而中间一行(即第 \(\frac{n+1}{2}\) 行)的第 \(2\) 到第 \(n-1\) 个字符都是 -,其余所有字符都是半角小写字母 a。例如,一个 \(n=5\) 的 H 字矩阵如下:

|aaa|
|aaa|
|---|
|aaa|
|aaa|

输入格式

输入只有一行包含一个正整数 \(n\)

输出格式

输出对应的 H 字矩阵。请严格按格式要求输出,不要擅自添加任何空格、标点、空行等任何符号。应该恰好输出 \(n\) 行,每行除了换行符外恰好包含 \(n\) 个字符。

输入输出样例

输入 #1

5

输出 #1

|aaa|
|aaa|
|---|
|aaa|
|aaa|

输入 #2

7

输出 #2

|aaaaa|
|aaaaa|
|aaaaa|
|-----|
|aaaaa|
|aaaaa|
|aaaaa|

数据规模与约定

保证 \(3 \le n \le 49\)\(n\) 是奇数。

解题思路

同样是二维矩阵构造问题。设中间行为 mid = n / 2(整数除法,因为n是奇数):

  • 最左列(\(j=0\))或最右列(\(j=n-1\)):输出 |
  • 中间行(\(i=mid\))且不是最左/最右列:输出 -
  • 其他位置:输出 a

C++ 代码实现

#include <iostream>
using namespace std;

int main() {
    int n;
    cin >> n;
    
    int mid = n / 2;  // 中间行的下标(0开始)
    
    for (int i = 0; i < n; i++) {      // 遍历每一行
        for (int j = 0; j < n; j++) {  // 遍历每一列
            if (j == 0 || j == n - 1) {
                // 最左列或最右列
                cout << "|";
            } else if (i == mid) {
                // 中间行的非边界位置
                cout << "-";
            } else {
                // 其他位置
                cout << "a";
            }
        }
        cout << endl;  // 每行结束换行
    }
    
    return 0;
}

关键点:

  1. 中间行下标计算:mid = n / 2(整数除法,例如 \(5/2=2\),对应第3行)
  2. 判断顺序很重要:先判断边界列(|>),再判断中间行(-),最后是 a
  3. 注意题目要求:中间一行只有第 \(2\) 到第 \(n-1\) 个字符是 -,这意味着最左最右列仍然是 |,所以判断边界列要放在前面
  4. 严格输出 \(n\) 行,每行恰好 \(n\) 个字符,不要有多余空格

总结对比

题目 题目链接 核心考点 矩阵特征 判断条件
B4037 N字矩阵 https://www.luogu.com.cn/problem/B4037 双重循环、条件判断 第1列、第n列、主对角线为+ j==0 || j==n-1 || i==j
B3924 H字矩阵 https://www.luogu.com.cn/problem/B3924 双重循环、条件判断 左右边为|>,中间横线为- 先判边界列,再判中间行

这两道题都是GESP的矩阵构造经典题目,重点考察双重循环的嵌套使用坐标位置的判断。解题时需要:

  1. 明确矩阵的行号和列号(从0还是从1开始)
  2. 理清各个特殊位置的判断条件
  3. 注意判断条件的优先级(如H字矩阵中边界列优先于中间行)
posted @ 2026-03-12 18:54  kkman2000  阅读(3)  评论(0)    收藏  举报