题目链接: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;
}