见注释
#include <bits/stdc++.h> #define FIO ios::sync_with_stdio(false),cin.tie(0),cout.tie(0) using namespace std; //typedef long long int ll; char goal[5][5] = { {'1', '1', '1', '1', '1'}, {'0', '1', '1', '1', '1'}, {'0', '0', '*', '1', '1'}, {'0', '0', '0', '0', '1'}, {'0', '0', '0', '0', '0'} };//目标的棋盘情况 char cur[5][5];//当前的棋盘情况 //骑士是走日字形的,我们把它的八种方向存储起来,方便待会遍历 int movex[8] = {1, 1, 2, 2, -1, -1, -2, -2}; int movey[8] = {2, -2, 1, -1, 2, -2, 1, -1}; int T;//测试用例数 int spacex, spacey;//存储当前空格的所在位置 int depth;//当前允许的步数 int getdata() {//获取当前的空格所在位置,和当前棋盘情况与目标棋盘情况的不同的位置数目 int num = 0; for (int i = 0; i < 5; i++) { for (int j = 0; j < 5; j++) { if (cur[i][j] == '*') { spacex = i; spacey = j; } if (cur[i][j] != goal[i][j]) { num++; } } } return num; } bool dfs(int cur_depth) { int difnum = getdata();//当前棋盘情况与目标棋盘情况的不同的位置的数目 int nowx = spacex, nowy = spacey;//记录下来 if (cur_depth + difnum - 1 > depth) return false;//不同的位置过于的多,而我们每移动一步,至多只能把一个位置变得合理 if (!difnum) return true;//没有不同的位置了 for (int i = 0; i < 8; i++) { int posx = nowx + movex[i], posy = nowy + movey[i]; if (posx < 0 || posy < 0 || posx > 4 || posy > 4) continue;//超出边界 swap(cur[posx][posy], cur[nowx][nowy]);//模拟移动 if (dfs(cur_depth + 1)) return true;//如果可行,则返回 swap(cur[posx][posy], cur[nowx][nowy]);//还原这次移动之前的情况,避免影响下一次的模拟 } return false; } int main() { FIO; cin >> T; while (T--) { for (auto & i : cur) cin >> i; depth = 0;//深度,也即现在所走的步数 while (depth <= 15 && !dfs(0)) depth++; if (depth == 16) cout << "-1" << endl; else cout << depth << endl; } return 0; }