hdu 1043 八数码--打表

来源:互联网 发布:音视频切换矩阵 编辑:程序博客网 时间:2024/04/29 16:21

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;}


0 0