HDU -1043 Eight (反向BFS+康托展开)

题目大意:将八数码的形式转变为最终形式所需要的步骤

解题思路:最终形式只有一种,可以用最终形式反向bfs推出可以变成那些八数码,标记并记录路径,对于每一种形式用康托展开来表示

#include<iostream>
#include<queue>

using namespace std;

int a[10],fac[10];
int d[4][2]={1,0,-1,0,0,1,0,-1};

struct node1 {
    char way;//记录路径 
    int fath;//记录父节点 
}Node[370000];

struct node2{
    int b[10];//记录当前序列 
    int n,son;//x在序列中的位置,当前康托值 
}; 

void cal_fac(){//计算阶乘 
    fac[0]=fac[1]=1;
    for(int i=2;i<=8;i++) fac[i]=fac[i-1]*i;
}

int cantor(int aa[]){//康托展开 
    int ans=0,k=0;
    for(int i=0;i<9;i++){
        k=0;
        for(int j=i+1;j<9;j++){
            if(aa[i]>aa[j]) k++;
        }
        ans+=k*fac[8-i];
    } 
    return ans;
}

void bfs(int a[]){
    queue<node2>Q; 
    node2 q;
    for(int i=0;i<9;i++) q.b[i]=a[i];
    q.n=8;q.son=0;
    Node[q.son].fath=0;//最终点的父节点置为自身
    Q.push(q);
    while(!Q.empty()){
        q=Q.front();Q.pop();
        for(int i=0;i<4;i++){
            node2 p=q; 
            int tx=p.n%3,ty=p.n/3;
            tx+=d[i][0],ty+=d[i][1];
            if(tx>=0&&tx<3&&ty>=0&&ty<3){
                p.n=ty*3+tx;//更新x的位置
                swap(p.b[p.n],p.b[q.n]);//交换移动位置的值
                p.son=cantor(p.b);
                if(Node[p.son].fath==-1){//若该康托值未被访问过
                    Node[p.son].fath=q.son;
                    if(i==0) Node[p.son].way='l';//反向bfs,记录反着来即可
                    else if(i==1) Node[p.son].way='r';
                    else if(i==2) Node[p.son].way='u';
                    else if(i==3) Node[p.son].way='d';
                    Q.push(p);
                }
            }
        }
    }
}

int main(){
    for(int i=0;i<370000;i++){
        Node[i].fath=-1;
    }
    for(int i=0;i<9;i++) a[i]=i+1;
    cal_fac();
    bfs(a);
    char ch[20];
    int t[10];
    while(gets(ch)>0){
        for(int i=0,j=0;ch[i]!='\0';i++){
            if(ch[i]=='x'){
                t[j++]=9;
            }
            else if(ch[i]>='0'&&ch[i]<='9'){
                t[j++]=ch[i]-'0';
            }
        }
        int tmp=cantor(t);
        if(Node[tmp].fath==-1){
            cout<<"unsolvable\n";
        }
        else {
            while(tmp!=0){
                cout<<Node[tmp].way;
                tmp=Node[tmp].fath;
            }
            puts("");
        }
    }
    
    return 0;
} 
View Code

参考博客:

https://www.bbsmax.com/A/lk5a0pR0J1

https://blog.csdn.net/ltrbless/article/details/87696372

猜你喜欢

转载自www.cnblogs.com/voids5/p/12719898.html