题目:
在一个 3×3 的网格中,1∼8 这 8 个数字和一个 x
恰好不重不漏地分布在这 3×3 的网格中。
例如:
1 2 3
x 4 6
7 5 8
在游戏过程中,可以把 x
与其上、下、左、右四个方向之一的数字交换(如果存在)。
我们的目的是通过交换,使得网格变为如下排列(称为正确排列):
1 2 3
4 5 6
7 8 x
求最少交换次数。
关键点:
将网格转换成字符串。处理字符串即可:原(r , c)与字符串位置关系:r = pos/3,c = pos%3;移动 x 同样转换为 pos 变化。
代码:
#include<iostream>
#include<queue>
#include<algorithm>
#include<string>
using namespace std;
queue<string> que;
unordered_map<string,int> dist;
int bfs(string& str)
{
dist[str] = 0;
que.push(str);
int ix[4] = {1,-1,0,0},iy[4] = {0,0,1,-1};
while(que.size())
{
string st = que.front();
que.pop();
//cout << que.size() << st <<endl;
int pos = st.find('x'),dis = dist[st];
for(int i = 0;i < 4;i++)
{
int a = pos/3+ix[i],b = pos%3+iy[i];
if(a >= 0 && a <=2 && b >= 0 && b <= 2)
{
int p1 = a*3 + b;
swap(st[pos],st[p1]);
if(!dist.count(st))
{
dist[st] = dis+1;
if(st == "12345678x")
return dist[st];
que.push(st);
}
swap(st[pos],st[p1]);
}
}
}
return -1;
}
int main()
{
string str;
char ch;
for(int i = 0;i < 9;i++) cin >> ch,str += ch;
//cout << str << endl;
cout << bfs(str) << endl;
return 0;
}