一、深度优先搜索
二、广度优先搜索
1、Wikioi 1004 四子连棋
题目描述 Description
在一个4*4的棋盘上摆放了14颗棋子,其中有7颗白色棋子,7颗黑色棋子,有两个空白地带,任何一颗黑白棋子都可以向上下左右四个方向移动到相邻的空格,这叫行棋一步,黑白双方交替走棋,任意一方可以先走,如果某个时刻使得任意一种颜色的棋子形成四个一线(包括斜线),这样的状态为目标棋局。
| ● |
○ |
● |
|
| ○ |
● |
○ |
● |
| ● |
○ |
● |
○ |
| ○ |
● |
○ |
|
输入描述 Input Description
从文件中读入一个4*4的初始棋局,黑棋子用B表示,白棋子用W表示,空格地带用O表示。
输出描述 Output Description
用最少的步数移动到目标棋局的步数。
样例输入 Sample Input
BWBO
WBWB
BWBW
WBWO
样例输出 Sample Output
5
这是一道很经典的广搜题,需要运用判重的知识,广搜过程应该很好理解,就是每次取出队首的状态,在队首的状态棋盘中找到两个空格,并将空格和相邻的棋子交换,要注意这里有先手和后手之分,BFS的状态应该包含棋盘、搜索步数、哈希值和最近下的棋的颜色,最近下的是白色,那么空格只能和黑棋交换,否则空格只能和白棋交换。判重也是一样,对于状态(s,最后下的是黑棋)和(s,最后下的是白棋)两种状态来说,虽然棋盘数组是一样的,但是最后下的棋颜色不同,最终的结果也会不同,因此判重数组应该是两维的:第一维是棋盘的哈希值,第二维是棋盘的最后下的棋的颜色,另外要注意,如果用三进制表示棋盘的哈希值,棋盘的哈希值<=3^16,这个范围明显超出了int表达范围,因此需要用Map容器保存棋盘哈希值这一个维度,也可以用string类型保存这个哈希值,或许会简单很多,但是要牺牲一点空间,如果想要空间不要时间,也可以用康托展开去保存哈希值,写起来复杂很多。
#include
#include
#include
#include
#include