大榕树——让我们共成长!
大榕树 myDrs.org
您的位置:大榕树 \ 编程       |  Logo语言   |  Pascal语言   |  信息学奥赛   |  高考保送    |  HTML版本
|  信息学奥赛>>解题报告>>SGOI7《仓库管理员》         本站全文搜索: 友情提示:

SGOI7《仓库管理员》
http://www.mydrs.org  3/23/2002  大榕树


这道题实际上就是大家熟知的"推箱子"游戏,它是从经典的迷宫最短路问题发展而来的,可采用广度优先搜索作为基本方法解题。所不同的是,迷宫问题只要前方没有障碍物便可以朝这个方向前进;而这道题还要求Sam能够"推动"箱子。也就是说,当我们在搜索中扩展一个节点的时候,还要检查Sam能否从当前位置到达和箱子前进方向相反的那个邻位上。

  在算法的实现中,我们不妨定义两个表示方向的常量:
  cfx:array[1..4] of shortint=(1,0,-1,0);
  cfy:array[1..4] of shortint=(0,1,0,-1);


  如果用(cx,cy)表示箱子的当前位置,要判断箱子能否前进到方格(cx+cfx[i],cy+cfy[i]),只要检查Sam能够从他的当前位置到达(cx-cfx[i],cy-cfy[i]),Sam的当前位置实际上也就是箱子上次被推动时所在的位置(队列中当前节点的父节点标记的位置)。另外,为了尽快确定Sam能否达到要求的位置,检查过程也应采用广度优先搜索,并在扩展到目标位置后立即退出,这将大大缩短检查的时间。

  明确的以上几点后,就不难写出程序的框架:它是两个嵌套的BFS,主过程的BFS搜索箱子的路径,在每次入队前调用另一个BFS寻找Sam的可达区域,确定改节点是否应该入队。

  这道题还有一个注意点:主BFS中标记一个方格是否被访问过,不能只记录方格的坐标,因为同一个方格有可能被走过不止一次。例如下面这个数据:

               

  Sam(红点)可以把箱子向前推两格后,绕道箱子后面,从原路便可将其推回目标位置(黄色方块)。这样,就有一些方格被访问了两次,而如果错误地做了访问标记,强制每个方格只能访问一次,则可能输出无解。然而,虽然同一个方格可以被多次访问,但从同一个方向上最多只能被访问一次。于是我们可以用一个三位数组used[x,y,d]标记是否从方向d上访问过方格(x,y),通过扩大状态表示解决上述问题。

  此外,搜索过程中应注意地图边界的处理,因为所给的数据不一定是封闭的。特殊情况的拦截也是本题测试点之一:如果所给的箱子位置已经在目标位置上,而Sam却无法接近箱子,就不该输出无解(例如输入数据7)。

作 者:陈昊罡
来 源:福州一中
共有3205位读者阅读过此文

  • 上篇文章:已经没有了
  • 下篇文章动态规划问题的经典实例

  • 发送邮件
    保存页面 打印文章 HTML版本 发表评论

    □- 近期热门文章 □- 相关文章
    1. NOIP2006竞赛大纲 [8307]
    2. 七类高中生具有保送资格 [5911]
    3. NOI2006获奖选手名单 [4956]
    4. 关于举办NOIP2006模拟赛的通告 [4107]
    5. Turbo Pascal各语句运行速... [3595]
    6. Turbo王者归来新Delphi免费... [3182]
    7. IOI2006我国4名选手全部获得金... [2946]
    8. 关于APIO2007与IOI2007... [2764]
    9. noip倒计时 by 枯叶蝴蝶 [2684]
    10. 朱泽园:思想上的金牌更重要 [2169]
    SGOI第14次友谊赛成绩
    SGOI-14友谊赛测试数据
    SGOI14友谊赛试题
    SGOI第十三次友谊赛数据
    SGOI第13次友谊赛成绩揭晓
    SGOI第十三次友谊赛试题
    SGOI第13次友谊赛竞赛规则
    Sgoi12之《黑白瓷砖》
    《哈利·波特与魔法石》
    Sgoi12之《网络传输》
     

    关于本站 | 合作伙伴 | 联系方式
    大榕树 版权所有 ©1999-2006 www.myDrs.org 闽ICP备05000721号