话说鄙人做这道题都有种把翔都做出来的感觉,主要是死在对string(一个自己不是很懂的东西)的不了解。然后一直在调bug,题意就是给你一个8宫格,然后0表示空缺,可以将相邻位的数字与空缺交换,以表示将该数字块移到空缺,然后会给你多组输入,每一组表示按从左到右,从上到下排列的8个数,问将这样排列的8个数移成01234567,最少移动多少步。输入有多组。先开始老老实实按题意从出发点开始移动,写完跑了一组就慢的不行了,再这玩意又是多组输入,所以从它给的输入开始搜,那岂不是超时妥妥的,后来看了下题解,才发现是要反的搞,何为反的搞,就是以01234567为出发点来BFS所有的可能,然后直接查找。这样搜一遍就OK了。
主要蛋疼的是我用了string,先开始一直没对string初始化,也就是一开始只写了string s;而没有像下面的代码一样写成string s = "00000000"(切记此时一定要是8个数,无论这8个数是几都行,但一定要8个数,我这里就直接用了8个0),这样没初始化s的话,s默认是没有长度的,但是访问它的单个节点位置确实行的通的,比如访问是s[0],s[1],之类的是可以查看的,虽然这是非法的。但编译器还是会让你过,因为string是一个封装好的类,它是一棵树,有上限空间,这是事先开辟好的,但是并不能访问,或者说访问是非法的。只有当你初始化了一定空间,这段被初始化的空间访问才是合法的,所以当你直接调用s时,若没初始化是得不到正确结果的。此题给的数量是8个数,所以应该初始8个字符大小的合法空间。为了这个问题,调了将近两个小时也是没谁了,,,,以后还是多多注意的好。。。。
#include<iostream>
#include<cstring>
#include<cstdio>
#include<cmath>
#include<queue>
#include<algorithm>
#include<map>
#include<string>
using namespace std;
map<string,int>mp;
queue<string>q;
int mov[4]= {-1,1,-4,4};
void bfs()
{
mp.clear();
mp["01234567"]=1;
q.push("01234567");
while(!q.empty())
{
string s=q.front();
q.pop();
int f=0;
for(int i=0; i<8; i++)
if(s[i]=='0')
{
f=i;
break;
}
for(int i=0;i<4;i++)
{
if(f+mov[i]<0||f+mov[i]>7||(f+mov[i]==4&&i==1)||(f+mov[i]==3&&i==0))continue;
string t=s;
swap(t[f],t[f+mov[i]]);
if(mp[t]==0)
{
mp[t]=mp[s]+1;
//cout<<t<<' '<<mp[t]<<endl;
q.push(t);
}
}
}
}
int main()
{
//freopen("in.in","r",stdin);
bfs();
int t;
string s="00000000";
while(scanf("%d",&t)!=EOF)
{
s[0]=t+'0';
for(int i=1;i<8;i++)
{
scanf("%d",&t);
s[i]=t+'0';
}
/*for(int i=0;i<8;i++)
printf("%c",s[i]);
printf("\n");*/
//cout<<s<<endl;
printf("%d\n",mp[s]-1);
}
return 0;
}