#include<iostream>
#include<queue>
#include<stack>
#include<memory.h>
#include<math.h>
#include<algorithm>
#define INF 400000
#define END 322560
using namespace std;
struct NODE
{
int board[3][3];
int x,y;
int h,g;
int state;
bool operator < (const NODE & node) const
{
return h != node.h ? h > node.h : g > node.g;
}
}sta;
int dir1[4][2] = {{0,-1},{0,1},{-1,0},{1,0}};
char dir2[4] = {'l','r','u','d'};
int fact[9] = {1,1,2,6,24,120,720,5040,40320};
int vis[INF],pre[INF];
void init(char *);
int get_hash(const NODE &);
void aStar();
void print();
int check(const NODE &);
int val(const NODE &);
int main()
{
char str[100];
// freopen("Sample Input.txt","r",stdin);
while(cin.getline(str,100))
{
init(str);
if(!check(sta))
{
cout << "unsolvable" << endl;
}
else
{
aStar();
print();
}
}
return 0;
}
void init(char str[])
{
int pos = 0;
for(int i = 0;i < 3;i++)
{
for(int j = 0;j < 3;j++)
{
int pos = (3 * i + j) * 2;
if(str[pos] == 'x')
{
sta.board[i][j] = 0;
sta.x = i;
sta.y = j;
}
else
{
sta.board[i][j] = str[pos] - '0';
}
}
}
sta.g = 0;
sta.h = val(sta);
sta.state = get_hash(sta);
memset(vis,-1,sizeof(vis));
memset(pre,-1,sizeof(pre));
vis[sta.state] = 1;
}
int get_hash(const NODE & node) //用康托展开获得此时排列在所有排列中的位置
{
int num[9];
for(int i = 0;i < 3;i++)
{
for(int j = 0;j < 3;j++)
{
num[3 * i + j] = node.board[i][j];
}
}
int res = 0;
for(int i = 0;i < 9;i++)
{
int cnt = 0;
for(int j = 0;j < i;j++)
{
if(num[j] > num[i])
{
cnt++;
}
}
res += cnt * fact[i];
}
return res;
}
void aStar()
{
priority_queue<NODE> que;
que.push(sta);
while(!que.empty())
{
NODE cur = que.top();
que.pop();
if(cur.state == END)
{
return;
}
for(int i = 0;i < 4;i++)
{
NODE next = cur;
next.x += dir1[i][0];
next.y += dir1[i][1];
if(next.x < 0 || next.y < 0 || next.x > 2 || next.y > 2)
{
continue;
}
swap(next.board[cur.x][cur.y],next.board[next.x][next.y]);
next.state = get_hash(next);
if(vis[next.state] < 0 && check(next))
{
vis[next.state] = i;
pre[next.state] = cur.state;
next.g++;
next.h = val(next);
que.push(next);
}
}
}
}
void print()
{
int pos = END;
stack<char> path;
while(pre[pos] != -1)
{
path.push(dir2[vis[pos]]);
pos = pre[pos];
}
while(!path.empty())
{
cout << path.top();
path.pop();
}
cout << endl;
}
int check(const NODE & node)
{
int num[9];
for(int i = 0;i < 3;i++)
{
for(int j = 0;j < 3;j++)
{
num[3 * i + j] = node.board[i][j];
}
}
int cnt = 0;
for(int i = 0;i < 9;i++)
{
if(num[i] == 0)
{
continue;
}
for(int j = 0;j < i;j++)
{
if(num[j] != 0 && num[j] > num[i])
{
cnt++;
}
}
}
if(cnt % 2 == 0)
return 1;
else
return 0;
}
int val(const NODE & node)
{
int sum = 0;
for(int i = 0;i < 3;i++)
{
for(int j = 0;j < 3;j++)
{
if(node.board[i][j])
{
sum += abs((node.board[i][j] - 1) / 3 - i) + abs((node.board[i][j] - 1) % 3 - j);
}
}
}
return sum;
#include<queue>
#include<stack>
#include<memory.h>
#include<math.h>
#include<algorithm>
#define INF 400000
#define END 322560
using namespace std;
struct NODE
{
int board[3][3];
int x,y;
int h,g;
int state;
bool operator < (const NODE & node) const
{
return h != node.h ? h > node.h : g > node.g;
}
}sta;
int dir1[4][2] = {{0,-1},{0,1},{-1,0},{1,0}};
char dir2[4] = {'l','r','u','d'};
int fact[9] = {1,1,2,6,24,120,720,5040,40320};
int vis[INF],pre[INF];
void init(char *);
int get_hash(const NODE &);
void aStar();
void print();
int check(const NODE &);
int val(const NODE &);
int main()
{
char str[100];
// freopen("Sample Input.txt","r",stdin);
while(cin.getline(str,100))
{
init(str);
if(!check(sta))
{
cout << "unsolvable" << endl;
}
else
{
aStar();
print();
}
}
return 0;
}
void init(char str[])
{
int pos = 0;
for(int i = 0;i < 3;i++)
{
for(int j = 0;j < 3;j++)
{
int pos = (3 * i + j) * 2;
if(str[pos] == 'x')
{
sta.board[i][j] = 0;
sta.x = i;
sta.y = j;
}
else
{
sta.board[i][j] = str[pos] - '0';
}
}
}
sta.g = 0;
sta.h = val(sta);
sta.state = get_hash(sta);
memset(vis,-1,sizeof(vis));
memset(pre,-1,sizeof(pre));
vis[sta.state] = 1;
}
int get_hash(const NODE & node) //用康托展开获得此时排列在所有排列中的位置
{
int num[9];
for(int i = 0;i < 3;i++)
{
for(int j = 0;j < 3;j++)
{
num[3 * i + j] = node.board[i][j];
}
}
int res = 0;
for(int i = 0;i < 9;i++)
{
int cnt = 0;
for(int j = 0;j < i;j++)
{
if(num[j] > num[i])
{
cnt++;
}
}
res += cnt * fact[i];
}
return res;
}
void aStar()
{
priority_queue<NODE> que;
que.push(sta);
while(!que.empty())
{
NODE cur = que.top();
que.pop();
if(cur.state == END)
{
return;
}
for(int i = 0;i < 4;i++)
{
NODE next = cur;
next.x += dir1[i][0];
next.y += dir1[i][1];
if(next.x < 0 || next.y < 0 || next.x > 2 || next.y > 2)
{
continue;
}
swap(next.board[cur.x][cur.y],next.board[next.x][next.y]);
next.state = get_hash(next);
if(vis[next.state] < 0 && check(next))
{
vis[next.state] = i;
pre[next.state] = cur.state;
next.g++;
next.h = val(next);
que.push(next);
}
}
}
}
void print()
{
int pos = END;
stack<char> path;
while(pre[pos] != -1)
{
path.push(dir2[vis[pos]]);
pos = pre[pos];
}
while(!path.empty())
{
cout << path.top();
path.pop();
}
cout << endl;
}
int check(const NODE & node)
{
int num[9];
for(int i = 0;i < 3;i++)
{
for(int j = 0;j < 3;j++)
{
num[3 * i + j] = node.board[i][j];
}
}
int cnt = 0;
for(int i = 0;i < 9;i++)
{
if(num[i] == 0)
{
continue;
}
for(int j = 0;j < i;j++)
{
if(num[j] != 0 && num[j] > num[i])
{
cnt++;
}
}
}
if(cnt % 2 == 0)
return 1;
else
return 0;
}
int val(const NODE & node)
{
int sum = 0;
for(int i = 0;i < 3;i++)
{
for(int j = 0;j < 3;j++)
{
if(node.board[i][j])
{
sum += abs((node.board[i][j] - 1) / 3 - i) + abs((node.board[i][j] - 1) % 3 - j);
}
}
}
return sum;
}
不知道为什么把priority_queue改成queue结果就不一样了,求解。。。。