八数码

Posted hhyx

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了八数码相关的知识,希望对你有一定的参考价值。

# 题意
在一个3*3的网格中有一个空格其余是1~8的数字不重不漏,

技术图片

每一次操作可以将空格和上下左右进行交换(如果存在)
使之最后变为

技术图片

过程如下

技术图片

求出最小的交换步骤
网格的输入用字符串输入

# 题解
将所有的状态看作图中的一个节点,如果某一个状态通过变换后能编导另一个状态,两个节点之间就连接一条边,bfs求最短路
每个状态都是3*3的矩阵,
1) 如何把状态存到队列之中----用字符串表示状态
2) 如何记录每一个状态的距离,dist用hash
3) 每次移动都是还原在矩阵中的坐标表然后再压缩回来

 1 #include<bits/stdc++.h>
 2 #define ll long long
 3 #define pb push_back
 4 using namespace std;
 5 unordered_map<string,int>dist;
 6 queue<string>que;
 7 string start;
 8 int dx[4]={0,0,1,-1},dy[4]={1,-1,0,0};
 9 int bfs(string start){
10    string end="12345678x";
11    que.push(start);
12    dist[start]=0;
13 
14    while(que.size()){
15       auto t=que.front();
16       que.pop();
17 
18       int d=dist[t];
19       if(t==end) return d;
20 
21       int k=t.find(x);
22       int x=k/3,y=k%3;
23       for(int i=0;i<4;i++){
24          int x_=x+dx[i],y_=y+dy[i];
25          if(x_ >= 0 && x_ < 3 && y_ >= 0 && y_ < 3) {
26             swap(t[k], t[x_ * 3 + y_]);
27 
28             if(!dist.count(t)){
29                dist[t]=d+1;
30                que.push(t);
31             }
32             swap(t[k],t[x_ * 3 + y_]);
33          }
34       }
35    }
36    return -1;
37 }
38 int main(){
39    ios::sync_with_stdio(0);
40    cin.tie(0);
41    cout.tie(0);
42    for (int i = 0; i <9 ; ++i) {
43       char c;
44       cin>>c;
45       getchar();
46       start+=c;
47    }
48    cout<<bfs(start);
49 }

 

以上是关于八数码的主要内容,如果未能解决你的问题,请参考以下文章

AcWing 179 八数码

八数码八境界代码

A*算法求解八数码难题(python实现)

[A*] aw179. 八数码(A*+bfs最小步数模型+模板题)

搜索进阶1八数码(HDU1043)

八数码问题判定是否解的证明