Eight 八数码题解

思路是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函数的推出。。

猜你喜欢

转载自blog.csdn.net/Leslie5205912/article/details/82842017