这题有人用宽搜做的,我反正宽搜严重超时
深搜加估值函数能过,要加几个剪枝
这题的估值函数 应该是 当 当前状态的骑士与目标状态的骑士的位置不同 的数量 加 已走步数 大于 15时 return
code:
// Forever_LF
#include<cstdio>
#include<cstring>
#include<iostream>
using namespace std;
struct node
{
int a[5][5];
int x,y,num;
node(){ num = 0; }
}st;
const int dx[8]={-2,-1,1,2, 2, 1,-1,-2};
const int dy[8]={ 1, 2,2,1,-1,-2,-2,-1};
int ans[5][5]={ {1,1,1,1,1},{0,1,1,1,1},{0,0,2,1,1},{0,0,0,0,1},{0,0,0,0,0} };
int result;
int find_( node x )
{
int i,j,k=0;
for( i=0;i<5;i++ )
for( j=0;j<5;j++ )
if( ans[i][j] != x.a[i][j] && x.a[i][j] !=2 )
k++;
return k;
}
void dfs( node x )
{
if( x.num >= result )return;
int k = find_( x );
if( k==0 )
{
result = min( result , x.num );
return;
}
else if( k+x.num > 15 )return ;
for( int i=0;i<8;i++ )
{
node y=x;
y.x+=dx[i];
y.y+=dy[i];
if( y.x<0 || y.x>4 ) continue;
if( y.y<0 || y.y>4 ) continue;
y.num++;
y.a[y.x][y.y]=2;
y.a[x.x][x.y]=x.a[y.x][y.y];
k = find_( y );
if( y.num + k < result ) dfs( y );
}
return;
}
int main()
{
int i,j,m,l;
char s;
scanf("%d",&m);
getchar();
while( m-- )
{
result = 999999;
for( i=0;i<5;i++ )
{
for( j=0;j<5;j++ )
{
scanf("%c",&s);
if( s == '*' )
{
st.a[i][j] = 2;
st.x = i;
st.y = j;
}
else st.a[i][j] = s - 48;
}
getchar();
}
dfs( st );
if( result>15 ) result=-1;
printf("%d\n",result);
}
return 0;
}