zoukankan      html  css  js  c++  java
  • 八数码问题

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

  • 相关阅读:
    ArcGIS 添加 MarkerSymbol 弹出“图形符号无法序列化为 JSON”错误
    C#中为特定类型增加扩展方法
    C# 访问Oracle数据库
    SQL Server2012中时间字段为DateTime和VarChar的区别
    Visual Studio2012调试时无法命中断点
    Prism框架研究(三)
    Prism框架研究(二)
    WPF Path总结(一)
    性能测试 -- 服务器参数调整
    eclipse-->run as --> maven test 中文乱码
  • 原文地址:https://www.cnblogs.com/hengli/p/3059552.html
Copyright © 2011-2022 走看看