题目不再过多描述,这里展示一些思路和做法。
一:A*算法
这里我们不难想到用bfs,但是根据八数码问题的一半经验,用普通的bfs很可能超时,故用启发式搜索A*算法。
在这里,我将估价函数设置为当前状态与目标状态各个数码的曼哈顿距离之和。不难证明估价函数的值一定小于等于真实距离的值,所以此估价函数正确。
AC代码:
#include<iostream>
#include<unordered_map>
#include<algorithm>
#include<queue>
#define x first
#define y second
using namespace std;
typedef pair<int,string> PIS;
int f(string s)
{
string endd="123804765";
int p[]={4,0,1,2,5,8,7,6,3};
int res=0;
for(int i=0;i<s.size();i++)
{
int num=s[i]-'0';
res+=abs(i/3-p[num]/3)+abs(i%3-p[num]%3);
}
return res;
}
int bfs(string start)
{
int dx[]={-1,0,1,0},dy[]={0,-1,0,1};
priority_queue<PIS,vector<PIS>,greater<PIS>> heap;
heap.push({f(start),start});
//cout<<f(start)<<endl;
unordered_map<string,int> dist;
dist[start]=0;
string endd="123804765";
while(heap.size())
{
PIS t = heap.top();
heap.pop();
string state=t.y;
if(t.y==endd) break;
int x,y;
for(int i=0;i<state.size();i++)
if(state[i]=='0')
x=i/3,y=i%3;
string init=state;
for(int i=0;i<4;i++)
{
int a=x+dx[i],b=y+dy[i];
if(a>=0 && a<3 && b>=0 && b<3)
{
swap(state[a*3+b],state[x*3+y]);