这道题用ASTAR算法的程序直接提交是不能通过的,必须要把中间查找过的状态都保存下来
//
2555620 2007-08-06 14:38:50 Accepted 1217 C++ 00:00.84 12696K Typhoon
#include < cstdio >
#include < cstdlib >
#include < cstring >
#include < algorithm >
#include < string >
#include < iostream >
using namespace std;
#define MAXN 362880
const int tar = 123456789 ,
pw[ 10 ] = { 1 , 10 , 100 , 1000 , 10000 , 100000 , 1000000 , 10000000 , 100000000 , 1000000000 },
jc[ 10 ] = { 1 , 1 , 2 , 6 , 24 , 120 , 720 , 5040 , 40320 , 362880 };
int s , st[ 10 ] , que[MAXN][ 4 ] , rear , front;
char ch[ 50 ];
bool used[MAXN] ;
string path[MAXN] ;
typedef struct {
int pos,v ;
}T ;
T heap[MAXN];
int hp = 0 ;
int cmp ( const T & a, const T & b ){
return a.v > b.v;
}
bool Isok(){
int i , j , sum ;
sum = 0 ;
for (i = 1 ;i < 10 ;i ++ )
for (j = i + 1 ;j < 10 ;j ++ ){
if (st[i] > st[j]) sum ++ ;
}
if (sum % 2 == 0 ) return true ;
return false ;
}
int Init(){
int len , i , q , c = 1 ;
len = strlen(ch);
s = 0 ;
for (i = 0 ;i < len;i ++ ){
if ((ch[i] >= ' 0 ' && ch[i] <= ' 9 ' ) || ch[i] == ' x ' ){
if (ch[i] == ' x ' ) q = c , st[q] = 10 ;
else {
if (s == 0 ) s = ch[i] - ' 0 ' ;
else s = s * 10 + ch[i] - ' 0 ' ;
st[c] = ch[i] - ' 0 ' ;
c ++ ;
}
}
}
s = s * 10 + q ;
memset(used, 0 , sizeof (used));
}
int Value( int a){
int t[ 9 ] , i , j , p;
for (i = 0 ;i < 9 ;i ++ ){
t[i] = a / pw[ 8 - i] % 10 ;
}
for (p = 0 , i = 0 ; i < 9 ; i ++ ){
if (t[i] == ' x ' ) continue ;
if (t[i] != i + 1 ){
j = t[i] - ' 1 ' ;
p += abs(i / 3 - j / 3 ) + abs(i % 3 - j % 3 );
}
}
return p ;
}
// 1R2L3U4D
int Right( int a ){ return a + 1 ;}
int Left ( int a){ return a - 1 ;}
int Up( int a ){
int t1,t2,t3 ;
t1 = 9 - a % 10 + 1 ;
t2 = a / pw[t1] ;
t3 = t2 / 1000 * 1000 + t2 % 100 * 10 + t2 / 100 % 10 ;
return t3 * pw[t1] + a % pw[t1] / 10 * 10 + a % 10 - 3 ;
}
int Down( int a ){
int t1,t2,t3,t4;
t1 = 9 - a % 10 + 1 ;
t2 = a / pw[t1] ;
t3 = a % pw[t1];
t4 = (t3 / pw[t1 - 2 ] + t3 / pw[t1 - 3 ] % 10 * 100 ) * pw[t1 - 3 ] + t3 % pw[t1 - 3 ] ;
return t2 * pw[t1] + t4 / 10 * 10 + a % 10 + 3 ;
}
int Hash( int a){
int t[ 9 ] , i , j , k , res = 0 ;
for (i = 0 ;i < 9 ;i ++ ){
t[i] = a / pw[ 8 - i] % 10 ;
}
for (i = 0 ;i < 8 ;i ++ ){
k = 0 ;
for (j = 0 ;j < i;j ++ )
if (t[i] < t[j]) k ++ ;
res += k * jc[i] ;
}
res += ( 9 - t[ 8 ]) * jc[ 8 ] ;
return res ;
}
int Find( int front){
int tmp , tt;
tmp = (que[front][ 0 ] % 10 - 1 ) % 3 ;
if (tmp < 2 ){
tmp = Right(que[front][ 0 ]);
tt = Hash(tmp);
if ( ! used[tt]){
used[tt] = 1 ;
que[rear][ 0 ] = tmp ;
que[rear][ 1 ] = 1 ;
que[rear][ 2 ] = front ;
que[rear][ 3 ] = que[front][ 3 ] + 1 ;
heap[hp].v = 10 * Value(tmp) + que[rear][ 3 ];
heap[hp].pos = rear;
push_heap(heap,heap + ( ++ hp),cmp);
rear ++ ;
}
if (path[tt].size())
return tmp ;
}
tmp = (que[front][ 0 ] % 10 - 1 ) % 3 ;
if (tmp > 0 ){
tmp = Left(que[front][ 0 ]);
tt = Hash(tmp);
if ( ! used[tt]){
used[tt] = 1 ;
que[rear][ 0 ] = tmp ;
que[rear][ 1 ] = 2 ;
que[rear][ 2 ] = front ;
que[rear][ 3 ] = que[front][ 3 ] + 1 ;
heap[hp].v = 10 * Value(tmp) + que[rear][ 3 ];
heap[hp].pos = rear;
push_heap(heap,heap + ( ++ hp),cmp);
rear ++ ;
}
if (path[tt].size())
return tmp ;
}
tmp = (que[front][ 0 ] % 10 - 1 ) / 3 ;
if (tmp < 2 ){
tmp = Down(que[front][ 0 ]);
tt = Hash(tmp);
if ( ! used[tt]){
used[tt] = 1 ;
que[rear][ 0 ] = tmp ;
que[rear][ 1 ] = 4 ;
que[rear][ 2 ] = front ;
que[rear][ 3 ] = que[front][ 3 ] + 1 ;
heap[hp].v = 10 * Value(tmp) + que[rear][ 3 ];
heap[hp].pos = rear;
push_heap(heap,heap + ( ++ hp),cmp);
rear ++ ;
}
if (path[tt].size())
return tmp ;
}
tmp = (que[front][ 0 ] % 10 - 1 ) / 3 ;
if (tmp > 0 ){
tmp = Up(que[front][ 0 ]);
tt = Hash(tmp);
if ( ! used[tt]){
used[tt] = 1 ;
que[rear][ 0 ] = tmp ;
que[rear][ 1 ] = 3 ;
que[rear][ 2 ] = front ;
que[rear][ 3 ] = que[front][ 3 ] + 1 ;
heap[hp].v = 10 * Value(tmp) + que[rear][ 3 ];
heap[hp].pos = rear;
push_heap(heap,heap + ( ++ hp),cmp);
rear ++ ;
}
if (path[tt].size())
return tmp ;
}
return 0 ;
}
int Get_path(){
string ans ;
if (que[front][ 0 ] == tar)
rear = front ;
else rear -- ;
int k = Hash(que[rear][ 0 ]);
ans = path[k] ;
while (rear != 0 ){
switch (que[rear][ 1 ]){
case 1 :ans += ' r ' ; break ;
case 2 :ans += ' l ' ; break ;
case 3 :ans += ' u ' ; break ;
default :ans += ' d ' ;
}
rear = que[rear][ 2 ] ;
int a = Hash(que[rear][ 0 ]);
path[a] = ans ;
}
}
int Solve(){
int i,tt;
T tm;
que[ 0 ][ 0 ] = s ;
que[ 0 ][ 3 ] = 0 ;
tt = Hash(s);
if (path[tt].size() != 0 ){
for (i = path[tt].length() - 1 ;i >= 0 ;i -- )
cout << path[tt][i];
cout << endl;
}
else {
used[tt] = 1 ;
hp = 0 ;
front = 0 , rear = 1 ;
while (que[front][ 0 ] != tar){
if (Find(front) != 0 ) break ;
front = heap[ 0 ].pos ;
pop_heap(heap,heap + (hp -- ),cmp);
}
Get_path();
tt = Hash(s) ;
for (i = path[tt].length() - 1 ;i >= 0 ;i -- )
cout << path[tt][i];
cout << endl;
}
}
int main(){
while (gets(ch)){
Init();
if (Isok()){
Solve();
}
else printf( " unsolvable " );
}
return 0 ;
}
/*
1 2 3 4 6 8 7 5 x
1 2 3 4 5 6 7 x 8
1 2 3 4 x 6 7 5 8
*/
#include < cstdio >
#include < cstdlib >
#include < cstring >
#include < algorithm >
#include < string >
#include < iostream >
using namespace std;
#define MAXN 362880
const int tar = 123456789 ,
pw[ 10 ] = { 1 , 10 , 100 , 1000 , 10000 , 100000 , 1000000 , 10000000 , 100000000 , 1000000000 },
jc[ 10 ] = { 1 , 1 , 2 , 6 , 24 , 120 , 720 , 5040 , 40320 , 362880 };
int s , st[ 10 ] , que[MAXN][ 4 ] , rear , front;
char ch[ 50 ];
bool used[MAXN] ;
string path[MAXN] ;
typedef struct {
int pos,v ;
}T ;
T heap[MAXN];
int hp = 0 ;
int cmp ( const T & a, const T & b ){
return a.v > b.v;
}
bool Isok(){
int i , j , sum ;
sum = 0 ;
for (i = 1 ;i < 10 ;i ++ )
for (j = i + 1 ;j < 10 ;j ++ ){
if (st[i] > st[j]) sum ++ ;
}
if (sum % 2 == 0 ) return true ;
return false ;
}
int Init(){
int len , i , q , c = 1 ;
len = strlen(ch);
s = 0 ;
for (i = 0 ;i < len;i ++ ){
if ((ch[i] >= ' 0 ' && ch[i] <= ' 9 ' ) || ch[i] == ' x ' ){
if (ch[i] == ' x ' ) q = c , st[q] = 10 ;
else {
if (s == 0 ) s = ch[i] - ' 0 ' ;
else s = s * 10 + ch[i] - ' 0 ' ;
st[c] = ch[i] - ' 0 ' ;
c ++ ;
}
}
}
s = s * 10 + q ;
memset(used, 0 , sizeof (used));
}
int Value( int a){
int t[ 9 ] , i , j , p;
for (i = 0 ;i < 9 ;i ++ ){
t[i] = a / pw[ 8 - i] % 10 ;
}
for (p = 0 , i = 0 ; i < 9 ; i ++ ){
if (t[i] == ' x ' ) continue ;
if (t[i] != i + 1 ){
j = t[i] - ' 1 ' ;
p += abs(i / 3 - j / 3 ) + abs(i % 3 - j % 3 );
}
}
return p ;
}
// 1R2L3U4D
int Right( int a ){ return a + 1 ;}
int Left ( int a){ return a - 1 ;}
int Up( int a ){
int t1,t2,t3 ;
t1 = 9 - a % 10 + 1 ;
t2 = a / pw[t1] ;
t3 = t2 / 1000 * 1000 + t2 % 100 * 10 + t2 / 100 % 10 ;
return t3 * pw[t1] + a % pw[t1] / 10 * 10 + a % 10 - 3 ;
}
int Down( int a ){
int t1,t2,t3,t4;
t1 = 9 - a % 10 + 1 ;
t2 = a / pw[t1] ;
t3 = a % pw[t1];
t4 = (t3 / pw[t1 - 2 ] + t3 / pw[t1 - 3 ] % 10 * 100 ) * pw[t1 - 3 ] + t3 % pw[t1 - 3 ] ;
return t2 * pw[t1] + t4 / 10 * 10 + a % 10 + 3 ;
}
int Hash( int a){
int t[ 9 ] , i , j , k , res = 0 ;
for (i = 0 ;i < 9 ;i ++ ){
t[i] = a / pw[ 8 - i] % 10 ;
}
for (i = 0 ;i < 8 ;i ++ ){
k = 0 ;
for (j = 0 ;j < i;j ++ )
if (t[i] < t[j]) k ++ ;
res += k * jc[i] ;
}
res += ( 9 - t[ 8 ]) * jc[ 8 ] ;
return res ;
}
int Find( int front){
int tmp , tt;
tmp = (que[front][ 0 ] % 10 - 1 ) % 3 ;
if (tmp < 2 ){
tmp = Right(que[front][ 0 ]);
tt = Hash(tmp);
if ( ! used[tt]){
used[tt] = 1 ;
que[rear][ 0 ] = tmp ;
que[rear][ 1 ] = 1 ;
que[rear][ 2 ] = front ;
que[rear][ 3 ] = que[front][ 3 ] + 1 ;
heap[hp].v = 10 * Value(tmp) + que[rear][ 3 ];
heap[hp].pos = rear;
push_heap(heap,heap + ( ++ hp),cmp);
rear ++ ;
}
if (path[tt].size())
return tmp ;
}
tmp = (que[front][ 0 ] % 10 - 1 ) % 3 ;
if (tmp > 0 ){
tmp = Left(que[front][ 0 ]);
tt = Hash(tmp);
if ( ! used[tt]){
used[tt] = 1 ;
que[rear][ 0 ] = tmp ;
que[rear][ 1 ] = 2 ;
que[rear][ 2 ] = front ;
que[rear][ 3 ] = que[front][ 3 ] + 1 ;
heap[hp].v = 10 * Value(tmp) + que[rear][ 3 ];
heap[hp].pos = rear;
push_heap(heap,heap + ( ++ hp),cmp);
rear ++ ;
}
if (path[tt].size())
return tmp ;
}
tmp = (que[front][ 0 ] % 10 - 1 ) / 3 ;
if (tmp < 2 ){
tmp = Down(que[front][ 0 ]);
tt = Hash(tmp);
if ( ! used[tt]){
used[tt] = 1 ;
que[rear][ 0 ] = tmp ;
que[rear][ 1 ] = 4 ;
que[rear][ 2 ] = front ;
que[rear][ 3 ] = que[front][ 3 ] + 1 ;
heap[hp].v = 10 * Value(tmp) + que[rear][ 3 ];
heap[hp].pos = rear;
push_heap(heap,heap + ( ++ hp),cmp);
rear ++ ;
}
if (path[tt].size())
return tmp ;
}
tmp = (que[front][ 0 ] % 10 - 1 ) / 3 ;
if (tmp > 0 ){
tmp = Up(que[front][ 0 ]);
tt = Hash(tmp);
if ( ! used[tt]){
used[tt] = 1 ;
que[rear][ 0 ] = tmp ;
que[rear][ 1 ] = 3 ;
que[rear][ 2 ] = front ;
que[rear][ 3 ] = que[front][ 3 ] + 1 ;
heap[hp].v = 10 * Value(tmp) + que[rear][ 3 ];
heap[hp].pos = rear;
push_heap(heap,heap + ( ++ hp),cmp);
rear ++ ;
}
if (path[tt].size())
return tmp ;
}
return 0 ;
}
int Get_path(){
string ans ;
if (que[front][ 0 ] == tar)
rear = front ;
else rear -- ;
int k = Hash(que[rear][ 0 ]);
ans = path[k] ;
while (rear != 0 ){
switch (que[rear][ 1 ]){
case 1 :ans += ' r ' ; break ;
case 2 :ans += ' l ' ; break ;
case 3 :ans += ' u ' ; break ;
default :ans += ' d ' ;
}
rear = que[rear][ 2 ] ;
int a = Hash(que[rear][ 0 ]);
path[a] = ans ;
}
}
int Solve(){
int i,tt;
T tm;
que[ 0 ][ 0 ] = s ;
que[ 0 ][ 3 ] = 0 ;
tt = Hash(s);
if (path[tt].size() != 0 ){
for (i = path[tt].length() - 1 ;i >= 0 ;i -- )
cout << path[tt][i];
cout << endl;
}
else {
used[tt] = 1 ;
hp = 0 ;
front = 0 , rear = 1 ;
while (que[front][ 0 ] != tar){
if (Find(front) != 0 ) break ;
front = heap[ 0 ].pos ;
pop_heap(heap,heap + (hp -- ),cmp);
}
Get_path();
tt = Hash(s) ;
for (i = path[tt].length() - 1 ;i >= 0 ;i -- )
cout << path[tt][i];
cout << endl;
}
}
int main(){
while (gets(ch)){
Init();
if (Isok()){
Solve();
}
else printf( " unsolvable " );
}
return 0 ;
}
/*
1 2 3 4 6 8 7 5 x
1 2 3 4 5 6 7 x 8
1 2 3 4 x 6 7 5 8
*/