因为9!=362880,所以我们可以通过宽搜从目标找到所有可达的情况,然后利用stl中的mp标记出,最后可以log(n)的查询,属于先打表后查询,用十进制数标记状态
#include <iostream>
#include <algorithm>
#include <cstring>
#include <cstdio>
#include <map>
#include <queue>
#define MAX 13
#define N 700007
using namespace std;
typedef long long LL;
map<LL,int> mark;
LL pos[MAX];
LL state;
LL goal;
int num[MAX];
bool flag;
void init ( )
{
pos[0] = 1;
for ( int i = 1 ; i <= 10 ; i++ )
pos[i] = pos[i-1]*10;
goal = 0;
for ( int i = 0 ; i < 8 ; i++ )
goal += pos[i]*(i+1);
}
struct Node
{
int x,t,pre,id;
char op;
LL s;
}node[N];
int id = 1;
void set ( int a , int b , int c , LL d , char op )
{
node[id].x = a;
node[id].t = b;
node[id].pre = c;
node[id].s = d;
node[id].op = op;
node[id].id = id;
}
bool bfs ( )
{
queue<Node> q;
mark.clear();
set ( 8 , 0 , -1 , goal , 0 );
mark[goal] = 1;
q.push ( node[id++] );
while ( !q.empty( ) )
{
Node old = q.front();
// cout << old.s << endl;
int x = old.x;
for ( int i = 0 ; i < 9 ; i++ )
num[i] = (old.s/pos[i])%10;
q.pop ( );
if ( x-3 >= 0 )
{
LL s = old.s + num[x-3]*pos[x] + num[x]*pos[x-3]
- num[x-3]*pos[x-3] - num[x]*pos[x];
if ( !mark[s] )
{
mark[s] = id;
set ( x-3 , old.t+1 , old.id , s , 'd' );
q.push ( node[id++] );
}
}
if ( x+3 < 9 )
{
LL s = old.s + num[x+3]*pos[x] + num[x]*pos[x+3]
- num[x+3]*pos[x+3] - num[x]*pos[x];
if ( !mark[s] )
{
mark[s] = id;
set ( x+3 , old.t+1 , old.id , s , 'u' );
q.push ( node[id++] );
}
}
if ( (x-1)/3 == x/3 )
{
LL s = old.s + num[x-1]*pos[x] + num[x]*pos[x-1]
- num[x-1]*pos[x-1] - num[x]*pos[x];
if ( !mark[s] )
{
mark[s] = id;
set ( x-1 , old.t+1 , old.id , s , 'r' );
q.push ( node[id++] );
}
}
if ( (x+1)/3 == x/3 )
{
LL s = old.s + num[x+1]*pos[x] + num[x]*pos[x+1]
- num[x+1]*pos[x+1] - num[x]*pos[x];
if ( !mark[s] )
{
mark[s] = id;
set ( x+1 , old.t+1 , old.id , s , 'l' );
q.push ( node[id++] );
}
}
}
}
void dfs ( int id )
{
if ( node[id].pre == -1 ) return;
printf ( "%c" , node[id].op );
dfs ( node[id].pre );
}
int main ( )
{
// cout << 9*8*7*6*5*4*3*2*1<<endl;
init ( );
bfs( );
//cout << "dasdasdasdas" << endl;
char str[5];
while ( ~scanf ( "%s" , str ) )
{
if ( str[0] != 'x' ) state = str[0] -48;
else state = 0;
for ( int i = 1 ; i < 9 ; i++ )
{
scanf ( "%s" , str );
if ( str[0]!= 'x' ) state += ( str[0] - 48 )*pos[i];
}
// cout << goal << endl;
// cout << state << endl;
//int id = mark[state];
//dfs ( id )
int id = mark[state];
if ( state == goal ) puts ( "" );
else if ( id )
{
dfs ( id );
puts ( "" );
}
else puts ( "unsolvable" );
}
}