题目来源:http://wikioi.com/problem/1225/
分析:
宽搜+哈希
虽然用A*速度快,但编程繁琐而且容易出错。
宽搜较慢,但编程简单,思路清晰,而且此题数据范围不是很大,不会超时。
关于哈希,用stl中的map可以轻松解决。
具体做法:
对于每一个状态,、向不越界的方向扩展,将扩展出来的状态用hash判重,如果不重复,将新状态入队,同时将步数+1。
代码:
#include<iostream>
#include<algorithm>
#include<map>
#include<cstring>
#include<string>
using namespace std;
int head,tail,i,dang,gs,r2[182000],r3[182000];
string ccc,ch,r1[182000];
int main()
{
map<string,int> hash; //利用map实现哈希
cin>>ch;
for (i=0;i<ch.length();i++) if (ch[i]=='0') {dang=i; break;}
hash.insert(pair<string,int>(ch,1));
r1[1]=ch;r2[1]=0;r3[1]=dang;
head=1;tail=1;gs=1;
while (head<=tail)
{
string cc=r1[head],ccc;
if (r3[head]+1>=3) //向上
{
ccc=cc;
ccc[r3[head]]=ccc[r3[head]-3];
ccc[r3[head]-3]='0';
if (ccc=="123804765")
{
cout<<r2[head]+1;break;
}
else
if (hash.find(ccc)==hash.end()) //hsah判重
{
tail++;
gs++;
hash.insert(pair<string,int>(ccc,gs));
r2[tail]=r2[head]+1; //新状态入队
r1[tail]=ccc;
r3[tail]=r3[head]-3;
}
}
if (r3[head]+1<=6) //向下
{
ccc=cc;
ccc[r3[head]]=ccc[r3[head]+3];
ccc[r3[head]+3]='0';
if (ccc=="123804765")
{
cout<<r2[head]+1;break;
}
else
if (hash.find(ccc)==hash.end())
{
tail++;
gs++;
hash.insert(pair<string,int>(ccc,gs));
r2[tail]=r2[head]+1;
r1[tail]=ccc;
r3[tail]=r3[head]+3;
}
}
if ((r3[head]+1)%3!=0) //向右
{
ccc=cc;
ccc[r3[head]]=ccc[r3[head]+1];
ccc[r3[head]+1]='0';
if (ccc=="123804765")
{
cout<<r2[head]+1;break;
}
else
if (hash.find(ccc)==hash.end())
{
tail++;
gs++;
hash.insert(pair<string,int>(ccc,gs));
r2[tail]=r2[head]+1;
r1[tail]=ccc;
r3[tail]=r3[head]+1;
}
}
if ((r3[head]+1)%3!=1) //向左
{
ccc=cc;
ccc[r3[head]]=ccc[r3[head]-1];
ccc[r3[head]-1]='0';
if (ccc=="123804765")
{
cout<<r2[head]+1;break;
}
else
if (hash.find(ccc)==hash.end())
{
tail++;
gs++;
hash.insert(pair<string,int>(ccc,gs));
r2[tail]=r2[head]+1;
r1[tail]=ccc;
r3[tail]=r3[head]-1;
}
}
head++;
}
return 0;
}