要解决这类问题,关键在于找出决定一个位置是打印 # 还是 . 的内在规律。我们可以把这个 n×n 的字符画想象成一个坐标系,每一个位置都有一个行号 i 和一个列号 j。我们的任务就是找到一个通用的数学公式,对于每一个第 i 行第 j 列(下文简称 (i,j)),这个公式能告诉我们应该在此处画什么。
由于题目给定的 n 是一个奇数,所以这个菱形拥有一个完美的中心点。这个中心点的行号和列号都是 (n+1)/2。我们可以把这个中心位置记作 mid。现在,让我们观察一下菱形上的所有 # 点与这个中心点 (mid,mid) 的关系。
我们可以计算任意一点 (i,j) 到中心点的“曼哈顿距离”,这个距离的计算方式不是走直线,而是像在城市街区里走路一样,只能横着或竖着走,它的计算公式是abs(i - mid) + abs(j - mid),其中 abs 表示取绝对值。
通过对样例的观察和计算,我们可以发现一个非常优美的规律:所有构成菱形边界的 # 点,它们到中心点的曼哈顿距离都恰好等于 mid−1。例如,对于一个 5×5 的菱形,中心点是 (3,3),mid−1 就是 2。第一行的 # 在 (1,3),它到中心的距离是 ∣1−3∣+∣3−3∣=2+0=2;第二行的 # 在 (2,2),距离是 ∣2−3∣+∣2−3∣=1+1=2。所有 # 点都满足这个条件。
找到了这个规律后,程序就变得非常简单了。我们只需要用两层嵌套的循环来遍历从 (1,1) 到 (n,n) 的每一个坐标点。在循环内部,我们计算当前点 (i,j) 到中心点的曼哈顿距离,并判断它是否等于 mid−1。如果等于,就输出 #;如果不等,就输出 .。每当内层循环(即一行)结束时,我们输出一个换行符,这样就能绘制出完整的菱形了。
注:转载自洛谷,如侵删