- 定义队列 并 将初始状态入队
- 定义dx、dy的四个方向数组
- 从队列中取出一个状态
- 从当前状态周边的四个方向逐个搜索
- 如果搜索到的状态满足要求(题目要求、先前没有搜索过),将其入队
- 如果不满足要求,进行下一个方向的搜索(有时需要恢复之前的状态以便下一个方向的搜索)
- 返回题目所求值
下面以八数码问题举例:
using namespace std;
#include<iostream>
#include<queue>
#include<unordered_map>
int dx[4] = {0, 0, 1, -1};
int dy[4] = {1, -1, 0, 0};
int bfs(string state){
//从state变换到"12345678x"需要多少步变换
//从x开始的地方进行搜索,广度搜索借助队列
queue<string> q; //存储搜索状态
unordered_map<string, int> mp;//存储每种状态对应的交换次数
q.push(state);
mp[state] = 0;
while(q.size()){
string t = q.front();
q.pop();
if(t == "12345678x")return mp[t];
int x = t.find('x');//找到'x'在字符串中的位置
int u = x / 3, v = x % 3;//算出x对应的矩阵中的位置
//对四个方向进行搜索
for(int i = 0;i < 4;i++){
int u1 = u + dx[i];
int v1 = v + dy[i];
//查看当前搜索的位置是否越界
if(u1 >= 0 && u1 < 3 && v1 >= 0 && v1 < 3){
int distance = mp[t];
swap(t[u1 * 3 + v1], t[x]);//交换当前搜索的位置与x
//查看当前状态是否已经存储过
//已经存储过表示先前已经搜索过,那么当前的距离势必大于之前的,故抛去
if(mp.find(t) == mp.end()){
q.push(t);
mp[t] = distance + 1;
}
swap(t[u1 * 3 + v1], t[x]);//交换回来进行下一个周边位置的探索
}
}
}
return -1;
}
int main(){
string state;
char c;
for(int i = 0;i < 9;i++){
cin>>c;
state += c;
}
int ans = bfs(state);
cout<<ans;
return 0;
}