八數碼 HDU 1043 狀態壓縮,寬搜

2021-08-09 12:13:04 字數 1536 閱讀 2877

3*3的方格中有乙個x,可以將x與它相鄰的方塊交換,使最終結果為

1 2 3

4 5 6

7 8 x

用康拓展開式的方法,狀壓(也可以採用雜湊表),然後通過不斷的轉換實現用1~362880(9!)來記錄3*3中數字的狀態

記錄時,用9來代替x

再進行寬搜(從最終狀態開始),用乙個陣列來記錄達到各個狀態之前的狀態,並用另乙個陣列記錄這次的移動

注意,因為是從最後的狀態開始,所以方向與答案相反

#include

#define n 400000

using

namespace std;

struct str

;queueq;

int vis[n]

,a[4][

4],aa=

0,jc[10]

=,ans[n]

;char ch,ea[n]

;bool p[10]

,da[n]

;int

kt1(string u)

//將數字方格轉化為康拓展開式

sum+

=(cnt*jc[

8-i]);

}return sum;

}string kt2

(int u)

//將康拓展開式轉化為數字方格

while

(p[t]

) t++

; p[t]=1

; an[i]

=t+48;}

an[9]

=0;return an;

}int

main()

}//up

if(x!=1)

}if(!vis[

kt1(k)])

swap

(a[x]

[y],a[x-1]

[y]);}

//down

if(x!=3)

}if(!vis[

kt1(k)])

swap

(a[x]

[y],a[x+1]

[y]);}

//left

if(y!=1)

}if(!vis[

kt1(k)])

swap

(a[x]

[y],a[x]

[y-1])

;}//right

if(y!=3)

}if(!vis[

kt1(k)])

swap

(a[x]

[y],a[x]

[y+1])

;}}while(~

scanf

("%c"

,&ch)

) k+

=ch;

} t=

kt1(k);if

(!da[t]

)while

(t!=-1

)printf

("\n");

ch=getchar()

;}}

HDU1043 八數碼問題

include include include using namespace std 通過康托展開來hash 9 有362880 const int maxn 400000 int step maxn int p maxn 2 用於記錄與前面乙個的相對路徑 int d 10 用來統計0到9的階乘 ...

HDU 1043 八數碼問題 A 搜尋

by cxlove 第乙個a 搜尋,a 是一種啟發式搜尋,g為已花代價,h為估計的剩餘代價,而a 是根據f g h作為估價函式進行排列,也就是優先選擇可能最優的節點進行擴充套件。對於八數碼問題,以下幾個問題需要知道 判斷有無解問題 根據逆序數直接判斷有無解,對於乙個八數碼,依次排列之後,每次是將空位...

hdu 1043 八數碼 打表

題意 略 思路 其實怎麼看也是打表的思路比較容易想一些,不過a 搜尋真是神奇。而且打表快不少,可能和多組資料有關,其實a 也可以記憶化一下應付一下多組資料,大概也會快不少吧。思路很簡單,從最終狀態反向暴力bfs就可以了。因為所有狀態也已9!不是很多,主要用hash來去重就可以了。思維含量比a 簡單。...