八數碼問題,輸入9個字元代表乙個3*3的棋盤,對於能還原的輸入,輸出一段包含 u、d、l、r 操作的操作序列,不能還原的輸入輸出「unsolvable」
輸入有多組,所以考慮先預處理出所有情況的操作序列,再根據輸入進行輸出
因為要遍歷所有情況,所以選擇 bfs 即可,從結果出發,每操作一次,儲存一次該種情況對應的操作序列
另外對於棋盤的所有情況,與全排列類似,用 9 代替 x 進行康托對映,壓縮空間 康托展開
/*
hdu1043
八數碼 bfs搜尋 + 康托展開
*/#include
#include
#include
#include
#include
#include
using
namespace std;
struct node
;//階乘
vector<
int>c(
);bool vis[
400000];
queue qn;
map<
int, string> mis;
intcantor
(vector<
int>
& permutation)
res +
= a * c[permutation.
size()
- i -1]
;}return res;
}vector<
int>
decantor
(int num,
int n)
return res;
}void
bfs())
;}}if
(now.pos >2)
);}}
if(now.pos !=
2&& now.pos !=
5&& now.pos !=8)
);}}
if(now.pos <6)
);}}
}}void
ini())
;bfs()
;}intmain()
}}
搜尋高階 hdu 1043 Eight
a 因為每次移動都會影響乙個點的曼哈頓距離 不算x 構造h 為所有數字塊的曼哈頓距離和,用逆序數hash 算x 根據逆序數奇偶性 不算x 減掉無法到達的情況 在構造優先佇列時當f相同時按照g值從大到小排序,這樣又是乙個很給力的減枝 include include include using name...
康托展開 康托逆展開
x a n n 1 a n 1 n 2 a i i 1 a 1 0 其中a i 為當前未出現的元素中是排在第幾個 從0開始 這就是康托展開。康托展開可用 實現。編輯 把乙個整數x展開成如下形式 x a n n 1 a n 1 n 2 a i i 1 a 2 1 a 1 0 其中a i 為當前未出現的...
康托展開 逆康托展開
康托展開 問題 給定的全排列,計算出它是第幾個排列 求序列號 方法 康托展開 對於乙個長度為 n 的排列 num 1 n 其序列號 x 為 x a 1 n i a 2 n 2 a i n i a n 1 1 a n 0 其中a i 表示在num i 1 n 中比num i 小的數的數量 includ...