GESP 二级编程题:图形输出

图形输出是 GESP C++ 二级的必考编程题型,以矩形网格为基础,通过行列坐标判断输出不同字符,构成字母、几何图案等。典型题目包括 N 字、H 字、X 字矩阵、菱形、字母三角形等。


一、通用核心模板

所有图形输出题都可以套入双层循环 + 条件判断的固定框架,代码结构高度统一:

for(int i = 1; i <= 行数; i++)
{
    for(int j = 1; j <= 列数; j++)
    {
        if(/* 判断当前(i,j)是否为特殊位置 */) 
        {
            cout << 特殊字符; // 如 +、#、| 等
        }
        else
        {
            cout << 填充字符; // 如 -、.、* 等
        }
    }
    cout << endl; // 每行结束必须换行,位置固定在内层循环外
}

解题的核心,就是根据图案规律,写对 if 里的坐标判断条件。


二、位置判断通用方法

约定:i 代表当前行号(从上到下),j 代表当前列号(从左到右),循环默认从 1 开始计数。

1. 定点判断

仅少数固定位置为特殊字符,最典型的是矩形四个角。

  • 判断规则:同时约束行号和列号
  • 示例:左上角 i==1 && j==1,右下角 i==n && j==n

2. 横线判断

整行都是同一种特殊字符,如首行、末行、中间分隔线。

  • 判断规则:仅约束行号 i
  • 示例:第一行 i == 1,奇数矩阵的中间行 i == n/2 + 1

3. 竖线判断

整列都是同一种特殊字符,如左右边框、中间竖线。

  • 判断规则:仅约束列号 j
  • 示例:最后一列 j == n,中间列 j == n/2 + 1

4. 斜线判断

这是图形题的难点,有两种通用解法:

方法一:公式法(找行列数学规律)

  • 左上→右下斜线:同一斜线上,行号与列号的差值固定,最经典的主对角线满足 i == j
  • 右上→左下斜线:同一斜线上,行号与列号的和固定,副对角线满足 i + j == n + 1

方法二:变量模拟法(逐行跟踪列号)

用一个变量记录当前行斜线所在的列号,每遍历完一行,根据斜线方向对变量做偏移(左移 --、右移 ++)。

  • 优势:不用推导数学公式,直观不易错,适合菱形、多斜线的复杂图案
  • 核心逻辑:行号天然逐行递增,只需额外维护列号的变化即可

三、经典真题

例题1:B4037 [GESP202409 二级] 小杨的 N 字矩阵

图案特征

n 行 n 列的矩形,左右两条竖边 + 一条左上到右下的斜线,构成字母 N。
示例(n=5):

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

解法1:变量模拟法

int n;
cin >> n;
int c = 1; // 斜线所在列,初始在第1列
for (int i = 1; i <= n; i++)
{
    for (int j = 1; j <= n; j++)
    {
        // 第一列、最后一列、斜线所在列 输出 +
        if(j == 1 || j == n || j == c) 
        {
            cout << '+';
        }
        else
        {
            cout << '-';
        }
    }
    cout << endl;
    c++; // 每往下一行,斜线向右移动1列
}

解法2:公式法

观察斜线规律:第 i 行的斜线正好在第 i 列,直接用 i == j 判断即可,无需额外变量。

// 核心判断条件替换为
if(j == 1 || j == n || i == j)

例题2:B4498 [GESP202603 二级] 画画

图案特征

标准矩形边框:四个角为 +,上下边为 -,左右边为 |,内部用 * 填充。
示例(n=5):

+---+
|***|
|***|
|***|
+---+

参考代码

int n;
cin >> n;
for(int i = 1; i <= n; i++)
{
    for(int j = 1; j <= n; j++)
    {
        // 四个角:左上、左下、右上、右下
        if( (i==1 && j==1) || (i==n && j==1) || (i==1 && j==n) || (i==n && j==n) )
        {
            cout << '+';
        }
        else if(i == 1 || i == n) // 上下横边
        {
            cout << '-';
        }
        else if(j == 1 || j == n) // 左右竖边
        {
            cout << '|';
        }
        else // 内部填充
        {
            cout << '*';
        }
    }
    cout << endl;
}

例题3:B4412 [GESP202509 二级] 菱形

图案特征

由两条交叉斜线构成的菱形,上半部分向外张开,下半部分向内收拢,是图形题中目前难度最高的一道。
示例(n=5):

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

参考代码(变量模拟法)

int n;
cin >> n;
int mid = n / 2 + 1; // 中间行/中间列的位置
int c1 = mid; // 左侧斜线的列号
int c2 = mid; // 右侧斜线的列号

for (int i = 1; i <= n; i++)
{
    for (int j = 1; j <= n; j++)
    {
        if (j == c1 || j == c2)
        {
            cout << '#';
        }
        else
        {
            cout << '.';
        }
    }
    
    // 上半部分:左斜线左移,右斜线右移
    if(i < mid) 
        c1--, c2++;
    // 下半部分:左斜线右移,右斜线左移
    else 
        c1++, c2--;
    
    cout << endl;
}

关键注意点

  • 分界判断用 i < mid中间行走下半部分逻辑,避免斜线多偏移一步
  • 这道题要找规律的话得找四根线,我就不展示了,有兴趣的同学自己找找四条斜线点的四个对应规律

例题4:X 字矩阵(高频考点)

图案特征

两条对角线交叉构成 X 形,是斜线判断的基础题。
示例(n=5):

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

核心判断

直接用公式法,两条对角线分别对应行列相等、行列和为定值:

if(i == j || i + j == n + 1)
    cout << '#';
else
    cout << '.';

例题5:H 字矩阵(高频考点)

图案特征

左右两条竖线 + 中间一条横线,构成字母 H。

核心判断

if(j == 1 || j == n || i == n/2 + 1)
    cout << '*';
else
    cout << ' ';

例题6:B3837 [GESP202303 二级] 画三角形

图案特征

逐行递增的字母三角形,字符按字母表顺序循环。

参考代码

int n;
cin >> n;
char c = 'A'; // 当前输出的字母,从A开始
for (int i = 1; i <= n; i++)
{
    // 第i行输出i个字母,构成三角形
    for (int j = 1; j <= i; j++) 
    {
        cout << c;
        c++;
        if(c > 'Z') c = 'A'; // 超出Z则回到A,实现周期循环
    }
    cout << endl;
}

四、解题总结与避坑

  1. 优先掌握变量模拟法:斜线类题目优先用变量跟踪列号,比推导公式更不容易出错,适合考试快速写代码。
  2. 固定换行位置:换行必须写在内层循环结束、外层循环内部,多换、少换都会判格式错误。
  3. 注意下标起点:循环从 1 开始和从 0 开始,坐标规律会差 1,写代码前先确认计数起点。
  4. 边界条件校验:菱形、中间线等题目,一定要核对中间行的逻辑归属,避免偏移错误。
  5. 字符类型统一:题目要求的字符(大小写、符号)必须完全一致,不能出现笔误。

标签: none

评论已关闭

  • 上一篇: 递归
  • 下一篇: 没有了