首页 > 代码库 > codevs 1225:八数码难题【双向广搜】

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\n", 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;}

 

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