魔法数字 problem Bfs搜索

大家都很强, 可与之共勉。

魔法数字
(A.pas/.c/.cpp)
时间限制:1.0s,空间限制131072 KB
题目描述:
给一个六位数A 和另外一个六位数B.
你有一根魔法棒,初始时指向A 的最左边数字,每一次你可以选择下列操作
之一:
1.将当前魔杖指向的数字与最左端的一个数字调换位置。
2.将当前魔杖指向的数字与最右端的一个数字调换位置。
3.将当前魔杖指向的数字+1。(若当前魔杖指向的数字为9 则无效)
4.将当前魔杖指向的数字−1。(若当前魔杖指向的数字为0 则无效)
5.将当前魔杖向右移动一位。
6.将当前魔杖向左移动一位。
输入描述:
多组数据,处理到EOF
对于每组数据,包含两个6 位数A,B
输出描述:
对于每组数据,输出一行表示答案..
样例输入:
1
123456 654321
样例输出:
11
数据范围:
100%的数据保证:1 <= 数据组数 <= 200

哈希收好

#include <cstdio>
#include <cstring>

#define MaxN 3000005

#define HashXor 7712122068LL

#define HashOr 111827282LL

#define HashMod 1000007

#define HashAnd 2332333

const unsigned int cnt[] = { 1000000, 100000, 10000, 1000, 100, 10, 1 };

inline int abs ( int a )  { return a < 0 ? -a : a;  }

#define min(a, b)  ((a) < (b) ? (a) : (b))

int a, b, fr, tl, ans, ord, State_cnt, Val, nxt[HashMod], head[HashMod], tmp[10], target[10];

struct State  {
    int s, v;
    short go[6];
    State ( ) {     }
    State ( int s, int v ) : s ( s ), v ( v )  {    }
} Q[MaxN], cur;

inline int Hash_val ( int& x )  {
//  return ( ( ( x & HashAnd ) ^ HashXor ) | HashOr ) % HashMod;
    return x % HashMod;
//  puts ( "百度云无良哈希" ); 
}

inline short Insert ( int pos )  {
    static int val, next;
    val = Hash_val ( Q[pos].v );
    next = head[val];
    while ( next )  {
        if ( Q[next].v ^ Q[pos].v )  
            next = nxt[next];
        else  return 0;
    }
    nxt[pos] = head[val];
    head[val] = pos;
    return 1;
}

int Bfs ( int& init )  {
    static int pos, val, tmp[10];
    register int i;
    short flag;
    Q[1] = State ( 0, init * 10 );
    for ( i = 1; i ^ 6; ++i )  Q[1].go[i] = 0;
    Q[1].go[0] = 1;
    fr = 0, tl = 1;
    Insert ( 1 );
    while ( fr ^ tl )  {
        cur = Q[++ fr];
        Val = cur.v;
        ord = 6;
        while ( ~ord )  tmp[ord --] = Val % 10, Val /= 10;
        pos = tmp[6];
        flag = ( !pos || !tmp[pos] ) ? 0 : 1;
        if ( flag )  {  
            tmp[pos] ^ tmp[0] ? tmp[pos] ^= tmp[0] ^= tmp[pos] ^= tmp[0] : 0;
            for ( val = 0, i = 0; i ^ 7; ++i )
                val += tmp[i] * cnt[i];
            Q[++ tl] = cur;
            Q[tl].v = val;
            if ( Insert ( tl ) )  {
                Q[tl].go[0] = 1;
                ++Q[tl].s;
            }  else --tl;
            tmp[pos] ^ tmp[0] ? tmp[pos] ^= tmp[0] ^= tmp[pos] ^= tmp[0] : 0;
        }

        flag = ( pos == 5 || (!pos && !tmp[5]) ) ? 0 : 1;
        if ( flag )  {  
            tmp[pos] ^ tmp[5] ? tmp[pos] ^= tmp[5] ^= tmp[pos] ^= tmp[5] : 0;
            for ( val = 0, i = 0; i ^ 7; ++i )
                val += tmp[i] * cnt[i];
            Q[++ tl] = cur;
            Q[tl].v = val;
            if ( Insert ( tl ) )  {
                Q[tl].go[5] = 1;
                ++Q[tl].s;
            }  else --tl;
            tmp[pos] ^ tmp[5] ? tmp[pos] ^= tmp[5] ^= tmp[pos] ^= tmp[5] : 0;
        }

        if ( pos < 5 )  { 
            Q[++ tl] = cur;
            ++Q[tl].s, ++Q[tl].v;
            if ( Insert( tl ) )  {          
                Q[tl].go[pos + 1] = 1;  
            }   else --tl;
        }

        if ( pos )  {
            Q[++ tl] = cur;
            ++Q[tl].s, --Q[tl].v;   
            if ( Insert( tl ) )  {      
                Q[tl].go[pos - 1] = 1;  
            }   else --tl;
        }
    }
    return tl;
}

int main ( )  {
    freopen ( "A.in", "r", &_iob[0] );
    freopen ( "A.out", "w", &_iob[1] );
    register unsigned int i, j;
    while ( ~scanf ( "%d%d", &a, &b ) )  {
        if ( a == b )  {    puts ( "0" ); continue;   }
        memset ( head, 0, sizeof head );
        ord = 5;
        while ( ~ord )  target[ord --] = b % 10, b /= 10;
        State_cnt = Bfs ( a );
        ans = 0x3f3f3f3f;

        i = 1;
        loop:;
            Q[i].v /= 10;
            ord = 5;
            while ( ~ord )  tmp[ord --] = Q[i].v % 10, Q[i].v /= 10;
            static int step;
            step = Q[i].s;
            for ( j = 0 ; j < 6; ++j )
            if (target[j] ^ tmp[j] && !Q[i].go[j])  {
                step = 0x3f3f3f3f;
                break;
            }   else  step += abs(target[j] - tmp[j]);
            ans > step ? ans = step : 0;
        if ( ++i <= State_cnt )  goto loop;
        printf ( "%d\n", ans );
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值