zoukankan      html  css  js  c++  java
  • 【省选组】模拟 gmoj 3980. 推箱子

    经典的推箱子是一个来自日本的古老游戏,目的是在训练你的逻辑思考能力。在一个狭小的仓库中,要求把木箱放到指定的位置,稍不小心就会出现箱子无法移动或者通道被堵住的情况,所以需要巧妙的利用有限的空间和通道,合理安排移动的次序和位置,才能顺利的完成任务。

    这个游戏有一个相对简单的版本,就是只有一个木箱,要将其推到一个确定的目标位置。举个例子:
    ..#@.
    .X.O.
    ##..#
    其中“.”表示没有障碍的格子,“#”表示有障碍的格子,“X”表示目标位置(注意这个格子是没有障碍的),“O”是箱子(对于人来说箱子存在的格子是不能越过的),“@”是人的位置。注意上面这个情况是可以将箱子推到目标点去的,因为人只要向右一格,向下一格,然后推着箱子向左走两格,就完成了任务。
    而下面这个例子是无解的:
    ..#..
    .X.O.
    ##.@#
    现在我们的主人公想知道,对于一个给定的地图(与上面两个不同的是没有了箱子和人的初始位置),有多少种箱子和人的初始摆放方法(箱子的初始位置和人的初始位置和目标位置必须两两不同)能够使得箱子能被人成功地推到目标位置。

    这题真nm恶心

    做法的话oj上的题解已经非常详细了,但我还是用自己的话说一下。

    我们可以将箱子从终点开始反推,记录当前箱子位置和人在箱子的哪一侧。

    然后就是维护的问题。

    第一:

    判断人可不可以从箱子的这一边走到另一边,即判断两个点在不经过某一个点情况下是否连通。

    这个可以直接判断是不是在同一个点双里就行,但是因为一个点可能会在多个点双里所以我不会维护,用了题解的做法。

    下面贴上题解:

      1:x和y都不是z的后代,那么一定联通

      2:x和y有一个是z的后代,一个不是,一般性不妨设x 不是z的后代,那么如果low[vy(表示y所在的那个子树)]<dfn[z],x和y联通

      3:x和y是z的后代,并且他们在一颗子树中(vx==vy),那么连通。

      4:x和y是z的后代,low[vx]<dfn[z]&&low[vy]<dfn[z],那么连通。

    第二:

    判断在不经过某个点的情况下一个点与多少个点连通。

    我也是用的题解做法。。

    还是贴上题解:

      1:x不是y的后代,那么除了那些low[vi]>=dfn[y]的子树中的点到达不了,其他点(除了y)都能到达。

      2:x是y的儿子vi的后代并且low[vi]<dfn[y],那么除了那些low[vi]>=dfn[y]的子树中的点到达不了,其他点(除了y)都能到达。

      3:x是y的儿子vi的后代并且low[vi]>=dfn[y],那么能够到达vi子树中的点。

    这道题就这么结束了,但是细节真的挺多的。

  • 相关阅读:
    【JS教程08】数组及操作方法
    【JS教程07】事件属性及匿名函数
    【JS教程06】操作元素
    【JS教程05】获取元素的方法
    【JS教程04】条件语句
    多线程环境下非安全Dictionary引起的“已添加了具有相同键的项”问题
    GPT分区基础知识及如何在GPT分区上安装WIN7
    Jenkins TFS配置
    windows查看端口占用命令
    VS2015企业版序列号
  • 原文地址:https://www.cnblogs.com/Mohogany/p/13759399.html
Copyright © 2011-2022 走看看