搜索专练

来源:互联网 发布:在兴唐通信上班 知乎 编辑:程序博客网 时间:2024/04/29 04:31

哎。。要开始搜索和DP专练才行了,发现自己的状态设计题,好弱。。。。

http://162.105.81.212/JudgeOnline/problem?id=1475

双重bfs,比较水的题,一次bfs是最短的步数里面找到目标点,一个bfs判断该人能不能到改箱子的后面,这样才能往前面推一步,hash为推完箱子后人所在的位置和箱子所在的位置的状态,hash[][][][]判重,不过wa了很多次,不明白PKU special Judge 是不是真的,我方向 按 WNES就不断的wa,当时wa的就差点重敲代码了,后面再网上面看下 有一个人也遇到同样的问题:

当我方向顺序设置如下时, WA
char dir[] = {'w', 'n', 'e', 's'};
char DIR[] = {'W', 'N', 'E', 'S'};

当我再改为如下顺序时, AC
char dir[] = {'n', 's', 'w', 'e' };
char DIR[] = {'N', 'S', 'W', 'E' };

不明白为什么会是这样,我改了很久也没想到过去改变方向的顺序,YM这个看到special Judge了的人,还会改方向,ORZ。。。

没想到这样就AC了。。真是狂晕了。。。

顺便提一下:

http://acm.hdu.edu.cn/showproblem.php?pid=1254 是该题的弱化版, 题解:http://blog.csdn.net/yuhailin060/archive/2010/04/13/5482857.aspx

http://acm.hdu.edu.cn/showproblem.php?pid=1732 也是另一道推箱子。。参考代码:http://blog.csdn.net/yuhailin060/archive/2010/04/13/5482887.aspx

暂时贴到这里 后面会不断的更新。。

 

http://162.105.81.212/JudgeOnline/problem?id=2044   对我而言,次等状态设计题当每天取出顶礼膜拜。。呵呵。。

一看题知道要状态的设计就没什么思绪了,特别是加上位运算之后就更加想不明白,后来看了往上面的提示自己慢慢想才想明白;

需要注意的几点:

1 :只需记录正个country的四个角落就可知真个country时候连续多少天没下雨就可推出整个countriy的下雨状况;

2 :虽然有九个方向,但是一个框的左上角只可能出现在3*3的范围了内,按照网上面的缩减可以变成5个方向即对其%3就总是在其中。。

3 :最开初之时就得保留当天不能下雨的地方state[],用|运算操作,然后后面判断四个方格能不能扩展就&与当天的不能下雨状态 s&state[];

http://acm.xtu.edu.cn/OnlineJudge/index.php/problem/read/id/1345
再添一道BFS+位压缩;要注意的几点:

1 ,我是用字符来表示高手的,所有高手的数目可能超过255 ,后面会全部为‘ ’,会变成一个高手,所以我们这里要用int表示char来做hash;

2 ,起点走过之后,可以再次被走;

其他就是简单的bfs过程了;

小贴下这题的代码:

总结:要多做位压缩题,熟悉更多的状态设计题。

http://162.105.81.212/JudgeOnline/problem?id=2308 PKU  2308 [Dearboy's Puzzle]

此题是一道搜索好题,涉及到了状态搜索的两种方法,dfs+bfs;因为在消去两个相同的棋子时,我们不能确定先后的关系,所以我们这里可以利用回溯来穷举出所有的策略;在一个方格上我们要找出和改棋子相同的棋子所在的位置,此时可以用bfs,退出dfs的条件就是当所有的棋子全部被消去或者已经可以断定无法再想消去了;

基本框架:

但是这样的结果TLE了,所以我们要加上强剪枝才能过得去;

1 ,对于有棋子为奇数的必定要直接处理掉;

2 ,形如  ****

              *AB*
              *BA*

              ****

在搜索的过程中,显然可以之间判断不能完全消去了。。要直接跳出dfs;

有实验证明这个剪枝才是关键点,由此剪枝我由TLE -> 0 ms,暂居ranklist No 。1;

次剪枝的代码:

那么上上述的框架中就会加上flag代码;

至此此题就可以完全ac了。

PKU 3322 http://162.105.81.212/JudgeOnline/problem?id=3322 

bfs 水题,但是细节处理很麻烦,哎。。

状态设定:hash[i][j][3] 表示改个柱子占有(i,j)开头的两个格子,(什么是以(i,j)开头的两个格子呢,比如:

                 1 2 两个水平的格子那么(i,j)表示1, 

                 1 

                 2 两个竖直的格子,那么(i,j)也表示1 ;

hash的最后一维就是用来标记属于哪一种状态,0,只占一个格子的状态,1表示横放占两个,2表示竖放占两个。所用数据结构:

struct Node
{
      int x,y,state,st;
}; 

然后就是很水的一个bfs了,但是处理细节表示麻烦,不小心没看到“Impossible” 的情况wa了一次。。。 

                                 

http://162.105.81.212/JudgeOnline/problem?id=3221

题意:简化版的八数码问题,逆向bfs + 康拓展开;

                                   

 

  

 

 

 

 

原创粉丝点击