• 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]!='';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
    ";
            }
            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

    七月在野,八月在宇,九月在户,十月蟋蟀入我床下
  • 相关阅读:
    剑指offer-用两个栈实现队列
    Java数组判空的正确打开方式
    浏览器输入URL后后的过程
    HTTP状态码
    HTTP和HTTPS
    北京好未来公司linux面试题
    三剑客 -- sed
    三剑客 -- grep
    shell脚本
    自动化 -- expect
  • 原文地址:https://www.cnblogs.com/voids5/p/12719898.html
Copyright © 2020-2023  润新知