• codevs 1225:八数码难题【双向广搜】


    这里是传送门

    这道题用普通BFS是可以做的,但是很明显没得过,效率太低了。效率更高的算法A*和双向广搜都可取,这写一下双向广搜的。

    注意题目中的判重很重要,可以转化成九位数用hash来解决这个问题。

    #include <set>
    #include <string>
    #include <cstdio>
    #include <cstring>
    #include <iostream>
    #include <algorithm>
    #define oo 0x7f7f7f7f
    #define str string
    #define put(x) printf("%d
    ", x)
    #define cln(x) memset(x, 0, sizeof(x))
    using namespace std;
    
    str st;
    str s[100005][2];
    int h[2];
    int t[2];
    int b[100005][2];
    set <str> hash[2];
    
    void check(int x)
    {
        if ( hash[1-x].count( s[t[x]][x] ) )
        {
            for (int i = 1; i <= t[1-x]; i++)
                if ( s[i][1-x] == s[t[x]][x] )
                {
                    put(b[i][1-x]+b[t[x]][x]);
                    break;
                }
            exit(0);
        }
    }
    
    str get( str s, int i )
    {
        str x = s;
        int p = s.find('0');
        if ( i == 1 )
        {
            if ( p < 3 ) return "-1";
            swap( t[p], t[p-3] );
            return x;
        }
        if ( i == 2 )
        {
            if ( p == 0 || p == 3 || p == 6 ) return "-1";
            swap( t[p], t[p-1] );
            return x;
        }
        if ( i == 3 )
        {
            if ( p > 5 ) return "-1";
            swap( t[p], t[p+3] );
            return x;
        }
        if ( i == 4 )
        {
            if ( p == 2 || p == 5 || p == 8 ) return "-1";
            swap( t[p], t[p+1] );
            return x;
        }
    }
    
    void go(int x)
    {
        h[x]++;
        str ss = s[h[x]][x];
        int c = b[h[x]][x] + 1;
        for ( int i = 1; i <= 4; i ++ )
        {
            str sss = get( ss, i );
            if ( sss == "-1" || hash[x].count(sss) ) continue;
            else
            {
                hash[x].insert(sss);
                t[x]++;
                b[t[x]][x] = c;
                s[t[x]][x] = sss;
                check(x);
            } 
        }
    }
    
    void Double_BFS()
    {
        h[0] = h[1] = 0;
        t[0] = t[1] = 1;
        s[1][0] = st;
        s[1][1] = "123804765";
        while( h[0] < t[0] && h[1] < t[1] )
        {
            if (t[0] < t[1])
                go(0);
            else
                go(1);
        }
        
    }
    
    int main()
    {
        cin >> st;
        Double_BFS();
        return 0;
    }
  • 相关阅读:
    单例模式
    工厂方法模式
    简单工厂模式
    LoadRunner11.0下载及安装链接~(By网络)
    lombok 介绍及基本使用方法
    360浏览器拦截弹窗,window.open方式打不开新页面
    js生成二维码
    Filter过滤器的写法
    JavaScript获取浏览器类型与版本
    如何截取date类型的年月日部分?
  • 原文地址:https://www.cnblogs.com/GuanHuaEdison/p/6919140.html
Copyright © 2020-2023  润新知