大家都很强, 可与之共勉 。
1085: [SCOI2005]骑士精神
Time Limit: 10 Sec Memory Limit: 162 MB
Description
在一个5×5的棋盘上有12个白色的骑士和12个黑色的骑士, 且有一个空位。在任何时候一个骑士都能按照骑
士的走法(它可以走到和它横坐标相差为1,纵坐标相差为2或者横坐标相差为2,纵坐标相差为1的格子)移动到空
位上。 给定一个初始的棋盘,怎样才能经过移动变成如下目标棋盘: 为了体现出骑士精神,他们必须以最少的步
数完成任务。
Input
第一行有一个正整数T(T<=10),表示一共有N组数据。接下来有T个5×5的矩阵,0表示白色骑士,1表示黑色骑
士,*表示空位。两组数据之间没有空行。
Output
对于每组数据都输出一行。如果能在15步以内(包括15步)到达目标状态,则输出步数,否则输出-1。
Sample Input
2
10110
01*11
10111
01001
00000
01011
110*1
01110
01010
00100
Sample Output
7
-1
HINT
Source
[Submit]
迭代加深搜索
估价函数设为当前不相同的骑士个数 + 当前步数 <= 期望最大步数
/**************************************************************
Problem: 1085
User: Lazer2001
Language: C++
Result: Accepted
Time:588 ms
Memory:1848 kb
****************************************************************/
# include <cctype>
# include <cstdio>
# define By_Lazer int main ( ) { return 0 ; }
const int N = 100005 ;
struct IO {
char buf [1 << 20], *s, *t, ch ;
inline char pick ( ) {
return ( s == t ) ? ( t = buf + fread ( s = buf, 1, 1 << 20, stdin ), *s ++ ) : ( *s ++ ) ;
}
int x ;
inline operator int ( ) {
while ( ! isdigit ( ch = pick ( ) ) ) ;
for ( x = -48 + ch ; isdigit ( ch = pick ( ) ); x = x * 10 + ch - 48 ) ;
return x ;
}
} Read ;
short flag ;
int x, y ;
int a [6] [6] ;
int b [6] [6] = {
{ 1, 1, 1, 1, 1, 0 },
{ 0, 1, 1, 1, 1, 0 },
{ 0, 0, 2, 1, 1, 0 },
{ 0, 0, 0, 0, 1, 0 },
{ 0, 0, 0, 0, 0, 0 }
} ;
const int dx [8] = { -1, 1, -2, 2, -2, 2, -1, 1 }, dy [8] = { -2, -2, -1, -1, 1, 1, 2, 2 } ;
class Main {
public :
inline short Check ( ) {
for ( int i = 0 ; i < 5 ; ++ i )
for ( int j = 0 ; j < 5 ; ++ j )
if ( a [i] [j] ^ b [i] [j] )
return 0 ;
return 1 ;
}
inline short Eva ( ) {
int cnt = 0 ;
for ( int i = 0 ; i < 5 ; ++ i )
for ( int j = 0 ; j < 5 ; ++ j )
if ( a [i] [j] ^ b [i] [j] ) ++ cnt ;
return cnt ;
}
inline void Dfs ( int x, int y, int step, int& expected ) {
if ( flag ) return ;
if ( step == expected ) {
if ( Check ( ) ) flag = 1 ;
return ;
}
for ( int i = 0 ; i < 8 ; ++ i ) {
int x1 = x + dx [i], y1 = y + dy [i] ;
if ( x1 < 5 && x1 >= 0 && y1 < 5 && y1 >= 0 ) {
a [x] [y] ^= a [x1] [y1] ^= a [x] [y] ^= a [x1] [y1] ;
int val = Eva ( ) ;
if ( val + step <= expected )
Dfs ( x1, y1, step + 1, expected ) ;
a [x] [y] ^= a [x1] [y1] ^= a [x] [y] ^= a [x1] [y1] ;
}
}
}
Main ( ) {
for ( int T = Read ; T ; -- T, flag = 0 ) {
for ( int i = 0 ; i < 5 ; ++ i ) {
for ( int j = 0 ; j < 5 ; ++ j ) {
static char ch ;
while ( ( ch = Read.pick ( ) ) == ' ' || ch == '\n' ) ;
if ( ch == '1' ) a [i] [j] = 1 ;
else if ( ch == '0' ) a [i] [j] = 0 ;
else a [i] [j] = 2, x = i, y = j ;
}
}
if ( Check ( ) ) {
puts ( "0" ) ;
continue ;
}
for ( int i = 1 ; i <= 15 ; ++ i ) {
Dfs ( x, y, 0, i ) ;
if ( flag ) {
printf ( "%d\n", i ) ;
goto end ;
}
}
puts ( "-1" ) ;
end : ;
}
}
} Z ;
By_Lazer