题目链接:https://www.luogu.org/problem/show?pid=2324
题解:
经典迭代加深搜索
考虑到步数最大只有15步,用IDA*比较好,估价函数设为有几个点未到达目标位置,进行搜索即可
//by sdfzchy
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
int a[6][6];
int sx,sy;
int map[6][6]=
{
0, 0, 0, 0, 0, 0,
0, 1, 1, 1, 1, 1,
0,-1, 1, 1, 1, 1,
0,-1,-1, 2, 1, 1,
0,-1,-1,-1,-1, 1,
0,-1,-1,-1,-1,-1
};
int xx[8]={1,1,2,2,-1,-1,-2,-2};
int yy[8]={2,-2,1,-1,2,-2,1,-1};
int tmp[6][6];
bool check()
{
for(int i=1;i<=5;i++)
for(int j=1;j<=5;j++)
if(tmp[i][j]!=map[i][j]) return 0;
return 1;
}
bool calc(int cur,int dep)
{
for(int i=1;i<=5;i++)
for(int j=1;j<=5;j++)
if(tmp[i][j]!=map[i][j]) cur++;
return cur<=dep;
}
int tot;
bool dfs(int x,int y,int cur,int dep)
{
if(cur==dep) return check();
for(int i=0;i<8;i++)
{
int nx=x+xx[i];
int ny=y+yy[i];
if(nx<1||nx>5||ny<1||ny>5) continue;
swap(tmp[x][y],tmp[nx][ny]);
if(calc(cur,dep)) if(dfs(nx,ny,cur+1,dep)) return true;
swap(tmp[x][y],tmp[nx][ny]);
}
return 0;
}
int main()
{
int T;
scanf("%d",&T);
while(T--)
{
char s[10];
for(int i=1;i<=5;i++)
{
scanf("%s",s+1);
for(int j=1;j<=5;j++)
if(s[j]=='1') a[i][j]=1;
else if(s[j]=='0') a[i][j]=-1;
else sx=i,sy=j,a[i][j]=2;
}
for(int dep=0;dep<=16;dep++)
{
if(dep==16) {puts("-1");break;}
for(int i=1;i<=5;i++) for(int j=1;j<=5;j++) tmp[i][j]=a[i][j];
if(dfs(sx,sy,0,dep)) {printf("%d\n",dep);break;}
}
}
return 0;
}