解题思路:
bfs,将棋盘转化成一个整数表示其状态,比如我们到到达的状态是815736402,而样例给的输入状态是264137058,因为这些整数过大,标记数组开不下,所以可以用map来代替数组,写得时候注意些细节。
思路链接:
https://blog.csdn.net/qq_41636123/article/details/83010868
代码如下:
#include <iostream>
#include <queue>
#include <map>using namespace std;const int N = 4;
int mp[N][N];
map<int,int>vis;
map<int,int>step;
int dx[] = {-1,0,1,0},dy[] = {0,1,0,-1};//上 右 下 左
int r,c;//row,col
bool move_can(int u,int d)//判断空格能不能走
{for (int i = 2;i>=0;i--)for (int j = 2;j>=0;j--){mp[i][j] = u%10;u = u/10;if (mp[i][j]==0){r = i;c = j;//记录空格的位置}}if ((d==0 && r==0) || (d==1 && c==2) || (d==2 && r==2) || (d==3 && c==0) )return false;//我们控制空格移动,如果空格越界就return falsereturn true;
}int move_to(int u,int d)//进行空格交换,然后标记
{int xx = r +dx[d];int yy = c+dy[d];mp[r][c] = mp[xx][yy];mp[xx][yy] = 0;int tmp =0 ;for (int i = 0;i<3;i++)for (int j = 0;j<3;j++){tmp = tmp*10+mp[i][j];}return tmp;
}int bfs(int u)
{queue<int>q;vis[u] = 1;step[u] = 0;q.push(u);while(q.size()){int next = q.front();q.pop();if (next==123456780) return step[next];for (int i = 0;i<4;i++){if (move_can(next,i)){int v = move_to(next,i);if (!vis[v]){vis[v] = 1;step[v] = step[next]+1;q.push(v);}}}}return -1;
}int main()
{int state = 0;for (int i = 0;i<3;i++)for (int j = 0;j<3;j++){cin>>mp[i][j];state = state*10+mp[i][j];//将输入的数转换以后标记}cout<<bfs(state)<<endl;return 0;
}
让我们看看如果换一种输入方式,要怎么写呢?
- 八数码问题II-bfs和map标记