首页 > 代码库 > 八数码问题

八数码问题

#include <iostream>#include <cstdlib>#include <cstdio>#include <cstring>#include <algorithm>#include <queue>#include <set>using namespace std;/*2 6 4 1 3 7 0 5 88 1 5 7 3 6 4 0 21 2 3 4 5 0 7 8 61 2 3 4 5 6 7 8 0*/typedef int State[9];const int maxstate = 1000000;State st[maxstate], goal;        //状态数组, 所有状态都保存在这里 int dist[maxstate];              //距离数组set<int> vis;                    //编码 //如果需要打印方案,可以在这里加一个"父亲编号" 数组  int fa[maxstate]int fa[maxstate];void init_lookup_table();int try_to_insert(int s);int BFS();void solve();const int dx[] = {-1, 1, 0, 0};const int dy[] = {0, 0, -1, 1};void print(State s, int front){    for (int i = 0; i < 9; i++) {        if (i % 3 == 0) cout << endl;        cout << st[front][i] << " ";    }    cout << endl;}bool judge(int x, int y){    return (x >= 0 && x < 3) && (y >= 0 && y < 3);}void init_lookup_table(){    for (int i = 0; i < 9; i++) {        scanf("%d", &st[1][i]);        //起始状态     }    for (int i = 0; i < 9; i++) {        scanf("%d", &goal[i]);    }    vis.clear();}int try_to_insert(int s){    int code = 0;     //把st[s]映射到code    for (int i = 0; i < 9; i++) {        code = code * 10 + st[s][i];    }     if (vis.count(code)) return 0;    vis.insert(code);    return 1;         //HashCode }//BFS, 返回目标状态在st数组下标int BFS(){    init_lookup_table();              //初始化查找表     int front = 1, rear = 2;          //不使用下标0, 因为0被看作不存在     while (front < rear) {         State& s = st[front];         //用引用简化代码        if (memcmp(goal, s, sizeof(s)) == 0)  {            return front;             //找到目标状态,  成功返回         }        int z;        for (z = 0; z < 9; z++) {            if (!s[z]) break;         //找“0”的位置         }         int x = z / 3, y = z % 3;     //模拟 行, 列         for (int d = 0; d < 4; d++) { //四个方向             int newx = x + dx[d];            int newy = y + dy[d];            int newz = newx * 3 + newy; //模拟到一维数组的地方 , 空格将要移动到的地方                         if (judge(newx, newy)) {    //移动合法                 State &t = st[rear];    //得到队尾元素                memcpy(&t, &s, sizeof(s));    // 将将 s 添加到队尾                                 //数字 和 空格交换位置                  t[newz] = s[z];         //z位置为 空格                 t[z] = s[newz];                                dist[rear] = dist[front] + 1;     //更新新结点的距离值                if (try_to_insert(rear))  rear++; //如果成功插入查找表, 修改队尾指针             }        }        front++;     //拓展完毕, 修改队首指针         //打印         print(st[front], front);    }    return 0;        //失败 } void solve(){    int ans = BFS();    if (ans > 0) printf("%d\n", dist[ans]);    else printf("-1\n");}int main(){    solve();    return 0;    }

 

八数码问题