思路是bfs+hash
#include <iostream>
#include <queue>
#include <cstring>
#include <string>
using namespace std;
struct Step{
char dir;//the direction of pre-this
int parent;//pre-hash
};
struct Node {
int board[9];//board
int x_index;//the position of 'x'
int child;//value of next Node's hash
};
int dir[4][2] = { {1,0},{-1,0},{0,1},{0,-1} };
string direction = "udlr";//the direction is opposite
int fac[10];
Step step_set[370000];
void set_fac() {
fac[0] = 1;
for (int i = 1; i <=8; ++i) {
fac[i] = fac[i - 1] * i;
}
}
//for every board calculate the value of hash
int board_hash(int board[]) {
int k, ans=0;
for (int i = 0; i < 9; ++i) {
k = 0;
for (int j = i + 1; j < 9; ++j) {
if (board[i] > board[j]) {
++k;
}
}
ans += k*fac[8 - i];
}
return ans;
}
void bfs(int finish[]) {
queue<Node> Q;
Node current;
for (int i = 0; i <= 8; ++i) {
current.board[i] = finish[i];
}
current.x_index = 8;
current.child = 0;step_set[current.child].parent = 0;//means the end
Q.push(current);
while (!Q.empty()) {
current = Q.front();
Q.pop();
for (int i = 0; i < 4; ++i) {
Node next = current;
int tempx = current.x_index / 3 + dir[i][0];
int tempy = current.x_index % 3 + dir[i][1];
//be sure not to crossing
if (tempx < 0 || tempy < 0 || tempx>2 || tempy>2)continue;
next.x_index = tempx * 3 + tempy;
int t = next.board[current.x_index];
next.board[current.x_index] = next.board[next.x_index];
next.board[next.x_index] = t;
next.child = board_hash(next.board);
//check if ditto
if (step_set[next.child].parent == -1) {
step_set[next.child].parent = current.child;
step_set[next.child].dir = direction[i];
//put in queue
Q.push(next);
}
}
}
}
int main() {
string text;
memset(step_set, -1, sizeof(step_set));
int finish[9];
for (int i = 0; i <= 8; ++i)finish[i] = i + 1;
int board_input[9];
char b_t;
//input
set_fac();
bfs(finish);
while(getline(cin,text)){
char temp;
int j = 0;
for (int i = 0; i < text.size(); ++i) {
temp = text[i];
if (temp == ' ')continue;
else if (temp == 'x')board_input[j++] = 9;
else board_input[j++] = temp - '0';
}
int ans = board_hash(board_input);
if (step_set[ans].parent == -1) {
cout << "unsolvable" << endl;
continue;
}
while (ans) {
cout << step_set[ans].dir;
ans = step_set[ans].parent;
}
cout << endl;
}
}
这道题我真的做了好久 可能是我太菜了吧 看了题解才懂的 hash是抄题解的 但是这题的收获就是懂得了hash的应用,所以说这道题其实是没有完全懂的
讲一下思路吧 解法是用最终答案模板(即 12345678x)反推出所有可能性的模板,并在每一步之间借由step_set结构体数组建立联系 从而最后用输入的模板反推出步法 关键是hash函数的推出。。