这题和上题(走迷宫)的结构基本类似
问题在于:
第一:如何将所给予的字符串与3*3的数组联系起来?
设字符串的序号为k,则其在数组中的横坐标x=k/3,纵坐标y=k%3
第二:什么样的字符串可以认为是一个有可能的解?
用哈希表存储字符串和交换次数,如果字符串从未出现过,则存入哈希表中,哈希值为其交换次数
#include<iostream>
#include<algorithm>
#include<queue>
#include<unordered_map>
using namespace std;
int bfs(string& start){
//设定最终情况end
string end="12345678x";
//存储可能的状态
queue<string> q;
//哈希表,存储一个字符串出现的次数
unordered_map<string,int> d;
q.push(start);
d[start]=0;
//方向向量
int dx[4]={1,-1,0,0},dy[4]={0,0,1,-1};
while(!q.empty()){
auto item=q.front();
q.pop();
int distance=d[item];
//找到了,直接返回值
if(item==end) return distance;
int k=item.find('x');
int x=k/3,y=k%3;
for(int i=0;i<4;i++){
int a=x+dx[i],b=y+dy[i];
if(a>=0&&a<3&&b>=0&&b<3){
swap(item[k],item[3*a+b]);
//如果未出现过,则说明有一种全新的情况,存储在哈希表和队列中,哈希表对应的值为其交换次数
if(!d.count(item)){
d[item]=distance+1;
q.push(item);
}
swap(item[k],item[3*a+b]);
}
}
}
return -1;
}
int main(){
string c,start;
for(int i=0;i<9;i++){
cin>>c;
start+=c;
}
cout<<bfs(start);
return 0;
}