专栏文章

B4412 [GESP202509 二级] 菱形

B4412题解参与者 20已保存评论 19

文章操作

快速查看文章及其快照的属性,并进行相关操作。

当前评论
20 条
当前快照
1 份
快照标识符
@mink6dis
此快照首次捕获于
2025/12/02 03:45
3 个月前
此快照最后确认于
2025/12/02 03:45
3 个月前
查看原文
欢迎报名洛谷网校,期待和大家一起进步!
要解决这类问题,关键在于找出决定一个位置是打印 # 还是 . 的内在规律。我们可以把这个 n×nn \times n 的字符画想象成一个坐标系,每一个位置都有一个行号 ii 和一个列号 jj。我们的任务就是找到一个通用的数学公式,对于每一个第 ii 行第 jj 列(下文简称 (i,j)(i, j)),这个公式能告诉我们应该在此处画什么。
由于题目给定的 nn 是一个奇数,所以这个菱形拥有一个完美的中心点。这个中心点的行号和列号都是 (n+1)/2(n + 1) / 2。我们可以把这个中心位置记作 midmid。现在,让我们观察一下菱形上的所有 # 点与这个中心点 (mid,mid)(mid, mid) 的关系。
我们可以计算任意一点 (i,j)(i, j) 到中心点的“曼哈顿距离”,这个距离的计算方式不是走直线,而是像在城市街区里走路一样,只能横着或竖着走,它的计算公式是 abs(i - mid) + abs(j - mid),其中 abs 表示取绝对值。
考点提示
abs 函数是明确在 GESP 二级大纲中写出的考点哦。
abs(x) 的意思是,如果 x0x\geq 0,那么还是 xx。否则,如果 x<0x<0,那么就是 x-x。在数学语言中,abs(x) 写作 x|x|
通过对样例的观察和计算,我们可以发现一个非常优美的规律:所有构成菱形边界的 # 点,它们到中心点的曼哈顿距离都恰好等于 mid1mid - 1。例如,对于一个 5×55\times 5 的菱形,中心点是 (3,3)(3, 3)mid1mid - 1 就是 22。第一行的 #(1,3)(1, 3),它到中心的距离是 13+33=2+0=2|1-3| + |3-3| = 2+0 = 2;第二行的 #(2,2)(2, 2),距离是 23+23=1+1=2|2-3| + |2-3| = 1+1 = 2。所有 # 点都满足这个条件。
找到了这个规律后,程序就变得非常简单了。我们只需要用两层嵌套的循环来遍历从 (1,1)(1, 1)(n,n)(n, n) 的每一个坐标点。在循环内部,我们计算当前点 (i,j)(i, j) 到中心点的曼哈顿距离,并判断它是否等于 mid1mid - 1。如果等于,就输出 #;如果不等,就输出 .。每当内层循环(即一行)结束时,我们输出一个换行符,这样就能绘制出完整的菱形了。
参考代码:
CPP
for (int i = 1; i <= n; ++i) {
    for (int j = 1; j <= n; ++j) {
        if (abs(i - mid) + abs(j - mid) == mid - 1)
            cout << '#';
        else
            cout << '.';
    }
    cout << endl;
}

评论

19 条评论,欢迎与作者交流。

正在加载评论...