题目
题解思路
这题类似八数码,都是转换回一个状态,而且状态受到多影响,不能单纯的BFS操作,于是有了类似打表的方法,反向BFS。
用终点推出能到达的每一个位置,并存起来,这下就是整个图的状态对应数值的情况了,八数码用的康托展开hash出了图的每一个情况对应的数值,
这题数据量小,我们直接用map进行hash。将图一维化变成字符串。利用从没到过的新状态map值等于0来存入数值。
没用过 不太敢用 的小妙招
int pit = s.find('0'); //直接返回第一个0的位置
string a = s ;
swap(a[pit],a[pio]); //利用两个指针交换他们string里单个字符
AC代码
#include <iostream>
#include <cstdio>
#include <string>
#include <algorithm>
#include <map>
#include <queue>
using namespace std;
map <string ,int > ti;
int m[4] = {1,-1,4,-4};
void bfs()
{
string s = "01234567";
ti[s] = 1;
queue <string> q;
q.push(s);
while(!q.empty())
{
s = q.front();
q.pop();
int pit = s.find('0');
for (int i = 0 ; i < 4 ; i++ )
{
int pio = pit + m[i] ;
if ((pit == 3 && pio == 4)|| (pit == 4 && pio == 3))
continue;
if (pio >= 0 && pio < 8 )
{
string a = s ;
swap(a[pit],a[pio]);
if (ti[a] == 0 )
{
ti[a] = ti[s] + 1;
q.push(a);
}
}
}
}
}
int main ()
{
bfs();
while(1)
{
string s="";//存放题目要求的卡牌序列
int a = 8,b;
while(a--)
{
if(!(cin >> b))
return 0;//这一行的处理是加了个结尾,不加的话死循环
s += b+'0';
}
cout <<ti[s] - 1<< endl;
}
return 0;
}