原题链接:P2670 [NOIP2015 普及组] 扫雷游戏 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)https://www.luogu.com.cn/problem/P2670
思路分析:
我们将这道题分为两个部分:
初始化:
实际上初始化这部分很简单--定义二维数组,然后循环即可(代码中使用Map和map数组)
代码如下:
状态转换(外加更新):
这部分实际上也很简单:
先说转移:
双重for循环会"自动"转移(严格意义来说,更像是移动,只不过是每次向某一行的右侧移动一格)
再说更新:
如果是"地雷"格,则保留原状态(也就是"*");
但如果是"安全"格,就要统计周围8个格子的"状态"--也就是每一个炸弹,该"安全"格的数值要加"1"(为了更加简单,你完全可以定义两个char类型的数组)
总结下来--暴力for循环就可以解决一切(暴力是世界上最好的算法思想)
代码如下:
组装一下,就可以得到我们想要的结果:
代码优化:
对于这道题目来说,暴力for循环就可以达到"AC"的目的,但实际上我们可以在状态转移的时候做一点优化。
实际上是这样的--在通过暴力方法时,每次我们只能去更新一个格子的状态--实际上,我们可以一次性"统计"中心格周围八个格子
说到这里你可能会联想到另一种算法思想--没错,就是"洪水覆盖"--也就是我们一次性向周围四个(上下左右四个方向;甚至可以是八个)进行拓展,并将该四个格子记为"已更新"(在更新过程中,我们可以跳过标记为"已更新"状态的格子,来达到log4N,甚至是log8N的效果)
但这样的操作也有缺点--我们需要额外创建数组--"状态数组(记录当前是否格子是否已经被访问过)",以及"转移数组(下一次要向哪里移动)"
代码如下:
ps:这里我们使用bool类型数组judge来记录各个格子是否已经被"检查过"