ZJU1217 Eigh

这道题用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


*/


 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值