您的位置:首页 > 其它

hdu 1043 反向bfs标号+dfs查询+stl+状态压缩

2015-02-12 22:27 253 查看
因为9!=362880,所以我们可以通过宽搜从目标找到所有可达的情况,然后利用stl中的mp标记出,最后可以log(n)的查询,属于先打表后查询,用十进制数标记状态

#include <iostream>
#include <algorithm>
#include <cstring>
#include <cstdio>
#include <map>
#include <queue>
#define MAX 13
#define N 700007

using namespace std;

typedef long long LL;

map<LL,int> mark;

LL pos[MAX];
LL state;
LL goal;
int num[MAX];
bool flag;

void init ( )
{
    pos[0] = 1;
    for ( int i = 1 ; i <= 10 ; i++ )
        pos[i] = pos[i-1]*10;
    goal = 0;
    for ( int i = 0 ; i < 8 ; i++ )
        goal += pos[i]*(i+1);
}

struct Node
{
    int x,t,pre,id;
    char op;
    LL s;
}node
;
int id = 1;

void set ( int a , int b , int c , LL d , char op )
{
    node[id].x = a;
    node[id].t = b;
    node[id].pre = c;
    node[id].s = d;
    node[id].op = op;
    node[id].id = id;
}

bool bfs ( )
{
    queue<Node> q;
    mark.clear();
    set ( 8 , 0 , -1 , goal , 0 );
    mark[goal] = 1;
    q.push ( node[id++] );
    while ( !q.empty( ) )
    {
        Node old = q.front();
       // cout << old.s << endl;
        int x = old.x;
        for ( int i = 0 ; i < 9 ; i++ )
            num[i] = (old.s/pos[i])%10;
        q.pop ( );
        if ( x-3 >= 0 )
        {
            LL s = old.s + num[x-3]*pos[x] + num[x]*pos[x-3]
                         - num[x-3]*pos[x-3] - num[x]*pos[x];
            if ( !mark[s] )
            {
                mark[s] = id;
                set ( x-3 , old.t+1 , old.id , s , 'd' );
                q.push ( node[id++] );
            }
        }
        if ( x+3 < 9 )
        {
            LL s = old.s + num[x+3]*pos[x] + num[x]*pos[x+3]
                         - num[x+3]*pos[x+3] - num[x]*pos[x];
            if ( !mark[s] )
            {
                mark[s] = id;
                set ( x+3 , old.t+1 , old.id , s , 'u' );
                q.push ( node[id++] );
            }
        }
        if ( (x-1)/3 == x/3 )
        {
            LL s = old.s + num[x-1]*pos[x] + num[x]*pos[x-1]
                         - num[x-1]*pos[x-1] - num[x]*pos[x];
            if ( !mark[s] )
            {
                mark[s] = id;
                set ( x-1 , old.t+1 , old.id , s , 'r' );
                q.push ( node[id++] );
            }
        }
        if ( (x+1)/3 == x/3 )
        {
            LL s = old.s + num[x+1]*pos[x] + num[x]*pos[x+1]
                         - num[x+1]*pos[x+1] - num[x]*pos[x];
            if ( !mark[s] )
            {
                mark[s] = id;
                set ( x+1 , old.t+1 , old.id , s , 'l' );
                q.push ( node[id++] );
            }
        }
    }
}

void dfs ( int id )
{
    if ( node[id].pre == -1 ) return;
    printf ( "%c" , node[id].op );
    dfs ( node[id].pre );
}

int main ( )
{
   // cout << 9*8*7*6*5*4*3*2*1<<endl;
    init ( );
    bfs( );
   //cout << "dasdasdasdas" << endl;
    char str[5];
    while ( ~scanf ( "%s" , str ) )
    {
        if ( str[0] != 'x' ) state = str[0] -48;
        else state = 0;
        for ( int i = 1 ; i < 9 ; i++ )
        {
            scanf ( "%s" , str );
            if ( str[0]!= 'x' ) state += ( str[0] - 48 )*pos[i];
        }
        // cout << goal << endl;
        // cout << state << endl;
        //int id = mark[state];
        //dfs ( id )
        int id = mark[state];
        if ( state == goal ) puts ( "" );
        else if ( id ) 
        {
            dfs ( id );
            puts ( "" );
        }
        else puts ( "unsolvable" );
    }
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: