BFS , 广度优先,
这里要实现一个hash函数,来对状态进行查重,我也不是很懂这个hash函数。得好好看一下,怎么实现一一映射的。
#include <iostream> #include <queue> #include <set> #include <string.h> using namespace std; const int MAX = 362880 + 10; int mileStone[10] = { 1, 1, 2, 6, 24, 120, 720, 5040, 40320, 362880 }; bool visit[MAX]; char path[MAX]; struct Node { int index; char direction; }parent[MAX]; //将n的排列映射到0...(n! - 1) int hash(const char* s) { int i, j, temp, num; num = 0; for (i = 0; i < 8; ++i) { temp = 0; for (j = 0; j < 9; ++j) { if (s[j] < s[i]) ++temp; } num += mileStone[s[i] - '1'] * temp; } return num; } void reverseStr(char* str) { int i, k = 0; char temp[100]; strcpy(temp, str); for (i = strlen(temp) - 1; i >= 0; --i) str[k++] = temp[i]; } void getStr(int num, char result[]) { int i = 0; while (num != 0) { result[i] = num % 10 + '0'; i++; num /= 10; } result[i] = 0; reverseStr(result); } int main() { int i, dir_x[4] = {0, 0, -1, 1}, dir_y = {1, -1, 0, 0}; char input[10], uname[5] = "rlud"; bool flag = false; for (i = 0; i < 9; ++i) { cin >> input[i]; if (input[i] == 'x') input[i] = '9'; } input[i] = 0; memset(visit, false, sizeof(visit)); memset(parent, -1, sizeof(parent)); queue<int> state; int head = atoi(input); int test = hash(input); visit[hash(input)] = true; state.push(head); while (!state.empty()) { int front = state.front(); state.pop(); char numStr[10]; getStr(front, numStr);//将int型的front,转为string for (i = 0; i < 9; ++i) { if (numStr[i] == '9') break; } int x = i / 3; int y = i % 3; //四个方向 for (i = 0; i < 4; ++i) { int xx = x + dir_x[i]; int yy = y + dir_y[i]; if (xx >= 0 && xx <= 2 && y >= 0 && yy <=2) { char newState[10]; strcpy(newState, numStr); char a = newState[3 * x + y]; newState[3 * x + y] = newState[3 * xx + yy]; newState[3 * xx + yy] = a; int newNum = atoi(newState); int pos = hash(newState); if (visit[pos]) continue; visit[pos] = true; //存储这个新的结点是从哪个方向来的,其父结点的哈希值是多少 parent[pos].direction = uname[i]; parent[pos].index = hash(numStr); state.push(newNum); if (newNum == 123456789) { flag = true; break; } } } if (flag) break; } if (flag) { i = 0; int pos1 = hash("123456789"), end = hash(input); node begin = parent[pos1]; while (pos1 != end) { path[i++] = begin.direction; pos1 = begin.index; begin = parent[pos1]; } path[i] = 0; reverseStr(path); cout << path << endl; } else { cout << "unsolvable" << endl; } return 0; }
列一下关于八数码问题的很好的资料:
http://hi.baidu.com/mcgrady32303/item/31f31a13ddf0225cf1090e37
http://www.cnblogs.com/JMDWQ/archive/2012/05/24/2517321.html A*算法
http://www.cnblogs.com/goodness/archive/2010/05/04/1727141.html 八数码的八境界