B4531 图形输出 坐标条件

南京名片

这节课只抓一个动作:给定字母、行号 i、列号 j,判断这个位置到底输出 `*` 还是空格。

一、先回答问题

结论

不用存整张图,边判断边输出

每个位置只由当前行列坐标决定。N 看三条线:左竖、右竖、主对角线;J 看上横、中竖、底部左半横。

N: j == 0 || j == n - 1 || i == j
J: i == 0 || j == mid || (i == n - 1 && j <= mid)
教学安排

先会判断一个格子,再输出一整行

图形题最怕“看起来像”但空格错。我们用 0 开始的坐标写代码,用 1 开始的行列给同学点格子检查。

最后把 N 的 n 个字符、一个分隔空格、J 的 n 个字符依次输出。

二、核心观察

把图形翻译成条件
N 的左右竖线

列号在最左或最右:`j == 0` 或 `j == n - 1`。

N 的主对角线

从左上到右下,每个格子满足 `i == j`。

J 的中间列

n 保证是奇数,所以中间列是 `mid = n / 2`。

J 的第一行

整行都是星号:`i == 0`。

J 的最后一行左半段

最后一行从第 0 列画到中间列:`i == n - 1 && j <= mid`。

两个字母之间

N 输出完一行后,额外输出恰好一个空格,再输出 J。

三、坐标检查器

当前位置判断
*

行绘制器

当前第 3 行会输出:

四、自己选答案

问题 1

n = 5,N 的第 4 行第 4 列输出什么?

问题 2

n = 7,J 的中间列在代码里是 j 等于多少?

问题 3

两个字母之间要输出几个分隔空格?

五、手推结果

位置类型 判断方法 课堂提醒
N 的某个格子 满足左列、右列、主对角线任意一个条件就输出 `*`。 `||` 表示“或者”,不是三个条件都要满足。
J 的某个格子 第一行、中间列、最后一行左半段任意一个条件成立。 最后一行不是整行,右半段仍然是空格。
一整行 先循环 j 输出 N,再输出一个空格,再循环 j 输出 J。 字母内部空白也要 `cout << ' '`,否则图形会挤在一起。

六、C++14 参考代码

B4531_solution.cpp
#include <bits/stdc++.h>
using namespace std;

int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);

    int n;
    cin >> n;
    int mid = n / 2;

    for (int i = 0; i < n; i++) {
        for (int j = 0; j < n; j++) {
            if (j == 0 || j == n - 1 || i == j) cout << '*';
            else cout << ' ';
        }
        cout << ' ';
        for (int j = 0; j < n; j++) {
            if (i == 0 || j == mid || (i == n - 1 && j <= mid)) cout << '*';
            else cout << ' ';
        }
        cout << '\n';
    }
    return 0;
}
坐标在代码里从 0 开始,所以第一列是 `j == 0`,最后一列是 `j == n - 1`。
`mid = n / 2` 正好得到 J 的中间列下标,因为 n 是奇数。
输出规模本来就是 O(n²),不需要额外数组,空间 O(1)。