#include <iostream>
#include <cstdio>
#include <map>
#include <queue>
#include <algorithm>
using namespace std;
queue<string> Q; //声明一个用于存放拼图的队列
map<string, int> Graph; //代表某拼图和从原拼图构成这个拼图步数的对应关系
string temp, now; //temp代表当前遍历的拼图,now代表当前遍历的拼图移动后生成的新拼图
int direction[4]={4,-4,-1,1}; //声明一个方向数组,这个数组代表0拼图的上下和左右移动
void bfs(); //代表进行广度优先搜索的函数
void bfs() //代表将原拼图进行移动,通过bfs穷举出移动后拼图的所有状况,将其储存在Graph中
{
int i;
Q.push("01234567"); //将原拼图进行入队
while (!Q.empty())
{
temp = Q.front();
Q.pop();
int pos = temp.find(‘0‘); //找出0拼图在字符串中的位置,根据题意,我们需要根据0拼图进行移动
for (i = 0; i < 4; i++)
{
int movepos = pos + direction[i]; //代表0地图(上下左右移动之后的位置)
if (movepos >= 0 && movepos < 8 && (!((pos == 0 || pos == 4) && i == 2) && !((pos == 3 || pos == 7) && i == 3))) //如果0地图移动之后的范围在拼图之内,并且0拼图在0位置或4位置时不能向左移,0拼图在3位置或7位置时不能向右移
{
now = temp;
swap(now[pos], now[movepos]); //将0拼图和0拼图所移动的方向进行交换
if(Graph[now] == 0) //如果交换过的拼图状态在Graph中还没有出现过
{
Graph[now] = Graph[temp] + 1;//将当前移动后的拼图的移动次数修改为当前遍历的地图的移动次数+1,代表当前移动后的拼图是由当前正在遍历的拼图移动一次变成的。
Q.push(now); //将新拼图进行入队
}
}
}
}
return;
}
int main()
{
bfs();
Graph["01234567"] = 0; //原拼图需要0步数就可以构成原拼图
while (true)
{
int count = 8; //代表输入的计数变量(要输入8个拼图)
int b; //代表要输入的单个拼图
string s = ""; //代表要输入的8个拼图,用变量s来表示
while (count--)
{
if (!(cin >> b)) //在测试平台中测试完毕之后会有一个结束标志EOF,所以当测试平台输入EOF时,这个函数就直接退出,从而避免死循环
{
return 0;
}
s += b + ‘0‘;
}
cout << Graph[s] << endl;
}
}
原文:https://www.cnblogs.com/gao79135/p/14027323.html