题目链接
https://www.lydsy.com/JudgeOnline/problem.php?id=1085
分析
直接DFS搜索树会很深,所以用迭代加深。
每次最多会让一个骑士到正确位置,所以可以用不在正确位置上的骑士数做估价函数,跑IDA*。
AC代码
#include <cstdio>
#include <iostream>
using namespace std;
inline int read() {
int num = 0;
char c = getchar();
while (c < '0' || c > '9') c = getchar();
while (c >= '0' && c <= '9')
num = num * 10 + c - '0', c = getchar();
return num;
}
const int maxn = 10;
const int next_x[8] = {-2, -2, 2, 2, -1, 1, -1, 1};
const int next_y[8] = {-1, 1, -1, 1, -2, -2, 2, 2};
int d;
char s[maxn][maxn], e[maxn][maxn];
inline int diff() {
int ret = 0;
for (int i = 1; i <= 5; ++i)
for (int j = 1; j <= 5; ++j)
if (s[i][j] != e[i][j])
++ret;
return ret;
}
inline int judge(int x, int y) {
return x >= 1 && x <= 5 && y >= 1 && y <= 5;
}
int dfs(int done, int x, int y) {
int cnt = diff();
if (done + cnt - 1 > d) return 0;
if (!cnt) return 1;
for (int i = 0; i < 8; ++i) {
int nx = x + next_x[i], ny = y + next_y[i];
if (!judge(nx, ny)) continue;
swap(s[x][y], s[nx][ny]);
if (dfs(done + 1, nx, ny)) return 1;
swap(s[x][y], s[nx][ny]);
}
return 0;
}
int main() {
for (int i = 1; i <= 5; ++i)
for (int j = 1; j <= 5; ++j)
e[i][j] = (i <= j) + '0';
e[3][3] = '*', e[4][4] = e[5][5] = '0';
int t = read(), x, y;
while (t--) {
for (int i = 1; i <= 5; ++i) {
scanf("%s", s[i] + 1);
for (int j = 1; j <= 5; ++j)
if (s[i][j] == '*') x = i, y = j;
}
d = 0;
while (d <= 15 && !dfs(0, x, y)) ++d;
if (d <= 15) printf("%d\n", d);
else printf("-1\n");
}
return 0;
}