八数码问题

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   八数码的八境界

posted on 2013-05-04 15:47  brainworm  阅读(174)  评论(0编辑  收藏  举报

导航