• luoguP1379-八数码难题(双向bfs)


    题目链接:https://www.luogu.org/problemnew/show/P1379

    题意:用字符串表示八数码,求根据给定八数码得到末状态“123804765”最少的步数。

    思路:这题很方便用双向bfs来优化,用两个队列分别从起点、终点开始搜索,两个map来记录该状态的步数。要注意的是起始状态和末状态相等的情况,需要特判。

    AC代码:

    #include<cstdio>
    #include<queue>
    #include<algorithm>
    #include<string>
    #include<map>
    #include<iostream>
    using namespace std;
    
    struct node{
        string s;
        int step,w;
    };
    
    int go[4]={-1,1,-3,3};
    queue<node> q1,q2;
    map<string,int> mp1,mp2;
    
    bool isOK(int w,int k){
        int x=w+go[k];
        if(x<0||x>8) return false;
        if(w%3==0&&k==0) return false;
        if(w%3==2&&k==1) return false;
        return true;
    }
    
    void bfs(){
        while(!q1.empty()&&!q2.empty()){
            node now1=q1.front();q1.pop();
            string s1=now1.s;
            int step1=now1.step,w1=now1.w;
            for(int i=0;i<4;++i){
                if(!isOK(w1,i)) continue;
                int ww=w1+go[i],st=step1+1;
                string ss=s1;
                swap(ss[w1],ss[ww]);
                if(mp1[ss]) continue;
                if(mp2[ss]){
                    printf("%d
    ",step1+mp2[ss]-1);
                    return;
                }
                mp1[ss]=st;
                node tmp={ss,st,ww};
                q1.push(tmp);
            }
            
            node now2=q2.front();q2.pop();
            string s2=now2.s;
            int step2=now2.step,w2=now2.w;
            for(int i=0;i<4;++i){
                if(!isOK(w2,i)) continue;
                int ww=w2+go[i],st=step2+1;
                string ss=s2;
                swap(ss[w2],ss[ww]);
                if(mp2[ss]) continue;
                if(mp1[ss]){
                    printf("%d
    ",step2+mp1[ss]-1);
                    return;
                }
                mp2[ss]=st;
                node tmp={ss,st,ww};
                q2.push(tmp);
            }
        }
    }
    
    int main(){
        string s;
        cin>>s;
        if(s=="123804765"){
            printf("0
    ");
            return 0;
        }
        int w;
        for(int i=0;i<s.length();++i)
            if(s[i]=='0'){
                w=i;break;
            }
        node bg={s,1,w};
        node ed={"123804765",1,4};
        mp1[s]=1,mp2["123804765"]=1;
        q1.push(bg),q2.push(ed);
        bfs();
        return 0;
    }
  • 相关阅读:
    spark shuffle 机制
    hive explain 源码分析
    前端jQurey
    js-dom操作
    前端JS
    前端CSS
    Redis和MongoDB区别
    MySQL数据库备份
    MySQL索引
    python连接mysql服务端
  • 原文地址:https://www.cnblogs.com/FrankChen831X/p/11203514.html
Copyright © 2020-2023  润新知