首页 > 代码库 > 八数码问题
八数码问题
#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; }
八数码问题
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。