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;
}
posted @ 2008-12-11 00:34  Beetlebum  阅读(676)  评论(0编辑  收藏  举报