相当于滑块拼图游戏
#include<bits/stdc++.h>
using namespace std;
int evaluate(string now)
{
int value=0;
for(int i=0;i<now.size();i++)
{
if(now[i]!='x')
{
int t=now[i]-'1';
value+=abs(i/3-t/3)+abs(i%3-t%3);
}
}
return value;
}
/*
012————i/3=0,i%3=i————(0,i)
345————(1,i)
678————(2,i)
*/
string bfs(string start)
{
string ed="12345678x";//终点状态
int dh[4]={-1,0,1,0},dl[4]={0,1,0,-1};//顺序是上右下左
string option="urdl";
unordered_map<string,int> dist;
unordered_map<string,pair<string,char>>pre;//记录上一步的状态和执行的操作
priority_queue<pair<int,string>,vector<pair<int,string> >,greater<pair<int,string> > >heap;
//队列中存放状态以及该状态所有点到其终点的距离之和,使用小顶堆,使得估价值最小的方案先出队
heap.push({evaluate(start),start});//初始状态入队
dist[start]=0;
while(heap.size())
{
auto t=heap.top();
heap.pop();
string now=t.second;
if(now==ed)break;
int step=dist[now];
int h,l;
for(int i=0;i<now.size();i++)
{
if(now[i]=='x')
{
h=i/3,l=i%3;//当前可移动块的位置
break;
}
}
string p=now;//当now状态改变后,状态p即为now状态的上一步
for(int i=0;i<4;i++)
{
int hh=h+dh[i],ll=l+dl[i];
if(hh<0||hh>=3||ll<0||ll>=3)continue;
swap(now[h*3+l],now[hh*3+ll]);//将当前可移动块与相邻拼图交换位置
if(!dist.count(now)||dist[now]>step+1)
{
dist[now]=step+1;
pre[now]={p,option[i]};//记录上个状态的选择
heap.push({dist[now]+evaluate(now),now});
}
swap(now[h*3+l],now[hh*3+ll]);
}
}
string op;
while(ed!=start)
{
op+=pre[ed].second;
ed=pre[ed].first;
}
reverse(op.begin(),op.end());
return op;
}
int main()
{
string str,temp;
char ch;
for(int i=0;i<9;i++)
{
cin>>ch;
str+=ch;
if(ch=='x')continue;
temp+=ch;
}
int jg=0;
for(int i=0;i<7;i++)
for(int j=i+1;j<8;j++)
if(temp[i]>temp[j])
jg++;
if(jg%2!=0)cout<<"unsolvable";
else cout<<bfs(str);
return 0;
}