大家都很强, 可与之共勉。
魔法数字
(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 );
}
}