P1058 [NOIP 2008 普及组] 立体图 题解

· · 题解

P1058 [NOIP 2008 普及组] 立体图 题解

原题链接

0x01 省流

题目大家应该都看得懂,这里就不多赘述了,我们的目标是绘制立体图,具体内容可结合样例。

0x02 分析

我们先不着手写,先想想下面这些问题。

遮挡关系

容易想到在保证遮挡关系的情况下,逐个绘制正方体,因此我们需要按照正确的顺序枚举。

不难发现绘制顺序的关键字即为:从深到浅、从左到右、从下到上,也就是依次按行、列、高度从小到大。

确定顶点

接下来就是比较难的绘制部分,我们先确定各个顶点的位置。

为了方便表述,下文中 x, y, z 分别代表正方体的行、列、高度。

每个顶点,无论位于正方体的哪个位置,都受到行、列、高度的影响。

以正面左下角顶点为例,不难得出它的位置(先行后列)为 \big(2(n - x) + 3z - 2, 2(n - x) + 4y - 3\big)

其余顶点的位置,请读者自行计算。(当然也可以抄作业)

确定顶点之后就好办了,绘制各条棱,最后再用空格填充三个面,没有任何技巧。

0x03 实现

思路基本差不多了,现在我们就来着手写。

我们先绘制一个正方体,然后输出。

然而你很快会发现问题,没有发现也没关系,等你写完就知道了(笑)。

正确地存图

补兑啊?立体图的大小是多少呢,而且我们是从下至上绘制,我们要从哪一行开始绘制。

我们很容易想到立体图的大小可以在绘制时动态更新,即不断取最大值。

而绘制的起始点……我们可以参照高精度的实现,将数组第一维(行)倒序存储,起始点就变为原点,只要输出时倒序输出即可。

由于代码过长,请前往剪贴板查看。

0x04 Changelog