[NOIP 2014復習]第二章:搜索
一、深度優先搜索
二、廣度優先搜索
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