借助八數碼問題,雙向廣搜,康托展開,逆序數奇偶性

2021-06-23 00:52:32 字數 1005 閱讀 9306

1.首先判斷是否有解

核心思想是根據一維狀態的逆序數奇偶性來判斷

將它表徵為一維狀態(0 1 2 3 4 5 6 7 8),它的逆序數為0,偶數。考慮數字的移動,左移or右移均不改變其一維狀態,因此逆序數的奇偶性不變。上移or下移時,一維狀態中某一位的數字往前或者往後跳了兩格(+/-2),相應的,逆序數+/-2,依然不改變奇偶性。因此有結論:八數碼問題有解 iff 初始狀態與終止狀態的逆序數奇偶性一致。

所以乙個完美的八數碼問題求解,必須先判斷其解是否存在,再行搜尋

2.雙向廣搜理論上可以減少一半的空間,時間。

1)將始 終狀態都入佇列並在相當的標記中為1,2(加以區分)

2)每次新的狀態的標記都與上次的相同,並判斷若有乙個標記走到了另乙個標記,結束

3)若要輸出過程,標記變化的地方要單獨輸出

乙個很好的模版 poj1915

#include #include int vis[305][305], mat[305][305];

int dx = ;

int dy = ;

int casenum, nnum, sx, sy, tx, ty, i;

struct point

cur, next, q[90005]=;

int isinbound(int x, int y)

;//康拖展開判重

// 0!1!2!3! 4! 5! 6! 7! 8! 9!

bool vis[maxn];//標記

string path[maxn];//記錄路徑

int cantor(int s)//康拖展開求該序列的hash值}}

}int main()

else cur.s[0]=ch-'0';

for(int i=1;i<9;i++)

else cur.s[i]=ch-'0';

}cur.status=cantor(cur.s);

if(vis[cur.status])

{cout<

康托展開 雙向廣搜

康托展開 公式 x a n n 1 a n 1 n 2 a i i 1 a 2 1 a 1 0 利用這個公式,我們可以求出在一列數中,已知的這一列數是這列數的全排列的字典序中的的幾個。我們可以應用康拓展開來求出一列數的全排列,也可以用康托展開進行判重。int kt int n,int s 擴充套件乙...

雙向廣搜 八數碼

雙向廣搜還是乙個很神奇的東西 判重更神奇 雙廣僅適用於有目標狀態的題目 include include include include include include include include include include using namespace std const int maxx...

八數碼問題(廣搜)

題目 描述 在九宮格裡放在1到8共8個數字還有乙個是空格,與空格相鄰的數字可以移動到空格的位置,問給定的狀態最少需要幾步能到達目標狀態 用0表示空格 1 2 3 4 5 6 7 8 0 輸入 輸入乙個給定的狀態。輸出 輸出到達目標狀態的最小步數。不能到達時輸出 1。輸入樣例 1 2 3 4 0 6 ...