hdu 1043 八数码--打表

http://acm.hdu.edu.cn/showproblem.php?pid=1043

 

题意:略;

 

思路:其实怎么看也是打表的思路比较容易想一些,不过A*搜索真是神奇。。。而且打表快不少,可能和多组数据有关,其实A*也可以记忆化一下应付一下多组数据,大概也会快不少吧。。。

思路很简单,从最终状态反向暴力BFS就可以了。。因为所有状态也已9!不是很多,主要用hash来去重就可以了。思维含量比A*简单。。

 

代码:

 

#include <bits/stdc++.h>

using namespace std;

const int dis[12] = {1,1,2,6,24,120,720,5040,40320,362880,3628800,39916800};
int tmp[10];
char s[10];
const int maxn=1e5*4;
int arr[10];
int vis[maxn];
int last[maxn+10];
int how[maxn+10];
int ans=-1;

int Cantor(int x, int len){
    int c=0;
    while(x){
        tmp[c++]=x%10;
        x/=10;
    }
    int resl = 1;
    for(int i = 0; i < len; i++){
        int counts = 0;
        for(int k = i + 1; k < len; k++){
            if(tmp[i] > tmp[k]){
                counts++;
            }
        }
        resl = resl + dis[len-i-1] * counts;
    }
    return resl;
}



int tran(int x,int h){
    int c=0,ret=0,idx=0;;
    while(x){
        tmp[c++]=x%10;
        if(tmp[c-1]==9) idx=c-1;
        x/=10;
    }
    if(h==0){
        if(idx<3) return -1;
        else swap(tmp[idx],tmp[idx-3]);
    }
    else if(h==1){
        if(idx%3==2) return -1;
        else swap(tmp[idx],tmp[idx+1]);
    }
    else if(h==2){
        if(idx>5) return -1;
        else swap(tmp[idx],tmp[idx+3]);
    }
    else if(h==3){
        if(idx%3==0) return -1;
        else swap(tmp[idx],tmp[idx-1]);
    }
    for(int i=0,j=1;i<9;i++,j*=10) ret+=tmp[i]*j;
    return ret;
}

struct node{
    int num,id;
    node(){};
    node(int b,int c):num(b),id(c){};
};

bool Astar(){
    memset(vis,-1,sizeof(vis));
    memset(last,-1,sizeof(last));
    queue<node> P;
    int x=0,cnt=0;
    for(int i=0,j=1;i<9;i++,j*=10) x+=arr[i]*j;
    P.push(node(x,cnt++));
    vis[Cantor(x,9)]=1;
    while(!P.empty()){
        node t=P.front();
        P.pop();
        ans=t.id;
        for(int i=0;i<4;i++){
            int x=tran(t.num,i);
            if(x!=-1&&vis[Cantor(x,9)]==-1){
                vis[Cantor(x,9)]=cnt;
                last[cnt]=t.id;
                how[cnt]=i;
                P.push(node(x,cnt++));
            }
        }
    }
    return false;
}

char re[maxn];

void pr(int x){
    int c=0;
    while(x!=0){
        if(how[x]==0) re[c++]='d';
        else if(how[x]==1) re[c++]='l';
        else if(how[x]==2) re[c++]='u';
        else if(how[x]==3) re[c++]='r';
        x=last[x];
    }
    for(int i=0;i<c;i++) printf("%c",re[i]);
    puts("");
}

int main(){
    for(int i=0;i<9;i++) arr[i]=i+1;
    Astar();
    while(cin>>s[0]>>s[1]>>s[2]>>s[3]>>s[4]>>s[5]>>s[6]>>s[7]>>s[8]){
        for(int i=0;i<9;i++){
            if(s[i]=='x') arr[i]=9;
            else arr[i]=(int)(s[i]-'0');
        }
        int ret=0;
        for(int i=0,j=1;i<9;i++,j*=10) ret+=arr[i]*j;
        if(ret==987654321) puts("");
        else if(vis[Cantor(ret,9)]!=-1){
            pr(vis[Cantor(ret,9)]);
        }
        else{
            puts("unsolvable");
        }
    }
    return 0;
}



 

posted @ 2016-10-22 16:50  zhangxianlong  阅读(128)  评论(0编辑  收藏  举报