pku1077 Eight

 

A*

Memory:6384K   Time:79MS

太烂了,估计是hash太肿...有空再来优化

#include  < iostream >
#include 
< string >
#include 
< vector >
#include 
< queue >
using   namespace  std;

#define  MAXN 362881

int  fac[ 9 ] = { 40320 , 5040 , 720 , 120 , 24 , 6 , 2 , 1 , 1 };
int  stseq[ 9 ],edseq[ 9 ] = { 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 0 },stkey,edkey;

int  g[MAXN],f[MAXN],mk[MAXN],pre[MAXN];
char  op[MAXN];

int  h( int  seq[ 9 ]){
    
int  i,ret = 0 ;
    
for (i = 0 ;i < 9 ;i ++ )
        ret
+= abs(seq[i] - edseq[i]);
    
return  ret;
    
// return 0;
}


int  getkey( int  seq[ 9 ]){
    
int  nsn,sum = 0 ;
    
for ( int  i = 0 ;i < 9 ;i ++ ){
        nsn
= 0 ;
        
for ( int  j = i + 1 ;j < 9 ;j ++ )
            
if (seq[i] > seq[j])
                nsn
++ ;
        sum
+= nsn * fac[i];
        
    }
    
return  sum;
}

void  getseq( int  key, int *   & seq, int   & pos){ // key of "876543210" = 40319 < 40320
     int  i,j,k;
    
for (i = 0 ;i < 9 ;i ++ ){
        seq[i]
= key / fac[i];
        key
%= fac[i];
    }

    
bool  used[ 9 ] = { 0 };
    used[seq[
0 ]] = true ;
    
if (seq[ 0 ] == 0 )
            pos
= 0 ;
    
for (i = 1 ;i < 9 ;i ++ ){
        j
= 0 ;
        
for (k = 0 ;j < seq[i]  &&  k < 9 ;k ++ )
            
if ( ! used[k])
                j
++ ;
        
while (used[k])
            k
++ ;
        seq[i]
= k;
        used[k]
= true ;
        
if (seq[i] == 0 )
            pos
= i;
    }

}


class  CP{
public :
    
int   operator ()( int  t1, int  t2){
        
return  f[t1] > f[t2];
    }
};

void  output( int  key){
    
int   * seq,i;
    
string  ans = "" ;
    seq
= new   int [ 9 ];
    
for (i = g[key] - 1 ;i >= 0 ;i -- ){
        ans
+= op[key];
        key
= pre[key];
    }
    
for (i = ans.length() - 1 ;i >= 0 ;i -- )
        cout
<< ans[i];
    cout
<< endl;
}

int  astar(){
    
int  curkey, * curseq,pos,nkey;
    curseq
= new   int [ 9 ];

    memset(mk,
0 , sizeof (mk));
    priority_queue
<   int , vector < int >  ,CP >  qu;

    stkey
= getkey(stseq);
    mk[stkey]
= 1 ;
    g[stkey]
= 0 ;
    f[stkey]
= g[stkey] + h(stseq);
    qu.push(stkey);

    f[
362880 ] =- 1 ;

    edkey
= getkey(edseq);

    
while ( ! qu.empty()){
        curkey
= qu.top();
        qu.pop();
        mk[curkey]
= 2 ;

        
if (curkey == edkey){
            output(curkey);
            
return  g[curkey];
        }

        getseq(curkey,curseq,pos);

        
if (pos >= 3 ){
            swap(curseq[pos],curseq[pos
- 3 ]);
            nkey
= getkey(curseq);
            
if (mk[nkey] == 0 ){
                mk[nkey]
= 1 ;
                pre[nkey]
= curkey;
                op[nkey]
= ' u ' ;
                g[nkey]
= g[curkey] + 1 ;
                f[nkey]
= g[nkey] + h(curseq);
                qu.push(nkey);
            }
            
else   if (mk[nkey] == 1 ){
                
if (g[curkey] + 1 < g[nkey]){
                    pre[nkey]
= curkey;
                    op[nkey]
= ' u ' ;
                    g[nkey]
= g[curkey] + 1 ;
                    f[nkey]
= g[nkey] + h(curseq);
                    qu.push(
362880 );
                    qu.pop();
                }
            }
            swap(curseq[pos],curseq[pos
- 3 ]);
        }

        
if (pos < 6 ){
            swap(curseq[pos],curseq[pos
+ 3 ]);
            nkey
= getkey(curseq);
            
if (mk[nkey] == 0 ){
                mk[nkey]
= 1 ;
                pre[nkey]
= curkey;
                op[nkey]
= ' d ' ;
                g[nkey]
= g[curkey] + 1 ;
                f[nkey]
= g[nkey] + h(curseq);
                qu.push(nkey);
            }
            
else   if (mk[nkey] == 1 ){
                
if (g[curkey] + 1 < g[nkey]){
                    pre[nkey]
= curkey;
                    op[nkey]
= ' d ' ;
                    g[nkey]
= g[curkey] + 1 ;
                    f[nkey]
= g[nkey] + h(curseq);
                    qu.push(
362880 );
                    qu.pop();
                }
            }
            swap(curseq[pos],curseq[pos
+ 3 ]);
        }

        
if (pos % 3 != 2 ){
            swap(curseq[pos],curseq[pos
+ 1 ]);
            nkey
= getkey(curseq);
            
if (mk[nkey] == 0 ){
                mk[nkey]
= 1 ;
                pre[nkey]
= curkey;
                op[nkey]
= ' r ' ;
                g[nkey]
= g[curkey] + 1 ;
                f[nkey]
= g[nkey] + h(curseq);
                qu.push(nkey);
            }
            
else   if (mk[nkey] == 1 ){
                
if (g[curkey] + 1 < g[nkey]){
                    pre[nkey]
= curkey;
                    op[nkey]
= ' r ' ;
                    g[nkey]
= g[curkey] + 1 ;
                    f[nkey]
= g[nkey] + h(curseq);
                    qu.push(
362880 );
                    qu.pop();
                }
            }
            swap(curseq[pos],curseq[pos
+ 1 ]);
        }

        
if (pos % 3 != 0 ){
            swap(curseq[pos],curseq[pos
- 1 ]);
            nkey
= getkey(curseq);
            
if (mk[nkey] == 0 ){
                mk[nkey]
= 1 ;
                pre[nkey]
= curkey;
                op[nkey]
= ' l ' ;
                g[nkey]
= g[curkey] + 1 ;
                f[nkey]
= g[nkey] + h(curseq);
                qu.push(nkey);
            }
            
else   if (mk[nkey] == 1 ){
                
if (g[curkey] + 1 < g[nkey]){
                    pre[nkey]
= curkey;
                    op[nkey]
= ' l ' ;
                    g[nkey]
= g[curkey] + 1 ;
                    f[nkey]
= g[nkey] + h(curseq);
                    qu.push(
362880 );
                    qu.pop();
                }
            }
            swap(curseq[pos],curseq[pos
- 1 ]);
        }
    }

    
return   - 1 ;
}


int  main(){
    
int  i;
    
char  ch;

    
for (i = 0 ;i < 9 ;i ++ ){
        cin
>> ch;
        
if (ch == ' x ' )
            stseq[i]
= 0 ;
        
else
            stseq[i]
= ch - ' 0 ' ;
    }

    
if (astar() ==- 1 )
        cout
<< " unsolvable\n " ;

    
return   0 ;
}

你可能感兴趣的:(pku)