题解 P3693 【琪露诺的冰雪小屋】
orangebird · · 题解
嗯,一道看起来很恶心的模拟,实际上做起来大部分分还是很容易拿到的。
但貌似比赛的时候很少有人做,被题面长度吓住了吗?
第一个操作,放弹幕,很简单。
要注意如果琪露诺站在有冰砖的位置放弹幕,这个弹幕会直接被阻挡,等于无效。
第二个操作,收集冰砖,更简单。
直接遍历二维地图就可以了。
20分到手~
第三个操作,放冰砖。
注意一个细节,如果放到地面上,要把冷冻度归零。
30分到手,真容易
第四个操作,拿走冰砖。
不考虑摔碎的情况,非常好写,轻松50分到手
嗯,再来看看情况2...
什么?不是说好的模拟吗?怎么出来个找连通块?
好吧,这题不完全是模拟。
先删掉对应位置的方块,然后6遍BFS寻找连通块,注意如果某一块碰到了地面就不算悬空连通块。
大家内心:这么快就写完4/5了,这是什么辣鸡题,题面又长,难度又水。
出题人的内心是滑稽的
那么来看第五个操作,盖屋顶
*首先判断冰砖是否不足,直接遍历即可,有小细节。
*下来判断内部空间是否不足,第一种情况是屋顶太低,
第二种情况是四面墙挤到一起,没有内部空间。
*然后输出房屋内外有多少个冰砖,注意屋顶建成以后,高于屋顶的算作房屋外部,如果是之前放冰砖
时统计,这里就要跳坑了。
*接下来判断移除多余冰砖时屋顶会不会塌
和之前一样,BFS即可。
*接下来一个大坑来了,修复墙壁。
其他没问题,重点是四个角。
如果门没选在角落旁边,那么如果四个角有残缺,根本不用管它,因为看不到。
如果门选到角落旁边,缺角在房屋里面是有可能被看到的。
怎么解决呢?提供一个思路:查表。
我们用以下矩阵
a b
c d
来表示一堵墙角落的情况。假设a和c表示角方块,b和d表示相邻的边方块。0表示没有方块,1表示有方块。
那么对于
1 0
0 0
的情况,显然在房子内能看到c的缺损,所以要将c填上。
而对于
1 0
0 1
的情况,无需对c进行填补,因为d遮住了c使得c并不可见。
可以用方块摆一摆,比较直观。
#请注意一个开门位置有可能和两个角都相邻。
选择开门的位置时不妨采取估价的方法,以开门位置缺少的冰砖个数为第一关键字(越大价值越高),修补角花费的冰砖数量为第二关键字(越小价值越高),是否在正中间为第三关键字(是则价值更高)排序,选择价值最高的位置来开门即可。
*判断有没有门,上一个操作时应该顺便就弄了吧,没啥坑点。
*判断填补前墙壁是否完整,如果刚才修复墙壁的时候没注意到那个大坑,这里就会跳进去
*判断四角的完整程度,还是一样,修复墙壁的时候如果跳坑了,那么这里也跳坑了
*输出剩余冰砖数量,只要前面都写对了这里应该没问题。
*判断是否完美建造,同上。
好啦,这个题就结束了,已经有很多题解了,我自己代码写得太丑就不放了。
(std已经被hack掉好几次了,这次更新数据和题解也是发现了之前没注意到的特殊情况)
如果还发现一些非正确算法能通过此题,可以私戳我,我将会继续加强数据。非常感谢~