#include<iostream> #include<queue> #include<map> #include <cstdio> using namespace std; queue <int> q1;//记录状态 map <int, int> step;//记录步数 int dr[4] = {0, 1, 0, -1}; int dc[4] = {-1, 0, 1, 0}; int bfs(); bool canmoveto(int u, int dir); int moveto(int u, int dir); int main() { int n, ans; scanf("%d", &n); if(n == 123804765) {//特殊情况 printf("0\n"); return 0; } q1.push(n); step[n] = 0; ans = bfs(); printf("%d\n", ans); return (0); } int bfs() { int i, u, v; while(!q1.empty()) { u = q1.front(); q1.pop(); for(i = 0; i < 4; i++) { if(canmoveto(u, i)) {//如果能扩展 v = moveto(u, i);//v是u扩展的元素 if(v == 123804765)//如果v满足条件,就返回到达它的步数 return(step[u] + 1); if(!step.count(v))//如果v是未被扩展的,就入队 { q1.push(v); step[v] = step[u] + 1; } } } } return -1; } bool canmoveto(int u, int dir) { int i, j; int b[3][3]; int row, col; //队首0的位置 int r, c; //由队首拓展的0的位置 for(i = 2; i >= 0; i--) { for(j = 2; j >= 0; j--) { b[i][j] = u % 10; u /= 10; if(!b[i][j]) row = i, col = j; } } r = row + dr[dir]; c = col + dc[dir]; if(r >= 0 && r < 3 && c >= 0 && c < 3) return 1; return 0; } int moveto(int u, int dir) { int i, j; int b[3][3]; int row, col; int r, c; int v; for(i = 2; i >= 0; i--) { for(j = 2; j >= 0; j--) { b[i][j] = u % 10; u /= 10; if(!b[i][j]) row = i, col = j; } } r = row + dr[dir]; c = col + dc[dir]; b[row][col] = b[r][c]; b[r][c] = 0; v = 0; for(i = 0; i < 3; i++) for(j = 0; j < 3; j++) v = v * 10 + b[i][j]; return v; }
洛谷P1379_八数码游戏
猜你喜欢
转载自blog.csdn.net/jay__bryant/article/details/80247002
今日推荐
周排行