1085: [SCOI2005]骑士精神
搜索+剪枝
BZOJ 1085
/**************************************************************
Problem: 1085
User: Dream_Tonight
Language: C++
Result: Accepted
Time:684 ms
Memory:1288 kb
****************************************************************/
#include <algorithm>
#include <iostream>
#include <cstring>
#include <vector>
#include <string>
#include <cstdio>
#include <cmath>
#include <stack>
#include <queue>
#include <list>
#include <map>
#include <set>
#include <iostream>
#include <cstdio>
using namespace std;
typedef long long ll;
typedef pair<int, int> pii;
const int maxn = 1e5 + 7;
const int inf = 0x7fffffff;
int n, s, e;
int mp[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 num[5][5], ans;
char ch;
int check() {
int result = 0;
for (int i = 0; i < 5; i++) {
for (int j = 0; j < 5; j++) {
if (num[i][j] != mp[i][j]) {
result++;
}
}
}
return result;
}
int zl[8] = {-1, 1, 2, -2, -2, 2, -1, 1}, zh[8] = {-2, -2, -1, -1, 1, 1, 2, 2};
void dfs(int x, int y, int d) {
int k = check();
if (k == 0) ans = min(ans, d);
if (d >= ans) return;
for (int i = 0; i < 8; i++) {
int dx = x + zl[i];
int dy = y + zh[i];
if (dx >= 0 && dx < 5 && dy >= 0 && dy < 5) {
swap(num[dx][dy], num[x][y]);
if (check() + d < ans) dfs(dx, dy, d + 1);
swap(num[dx][dy], num[x][y]);
}
}
}
int main() {
scanf("%d", &n);
while (n--) {
ans = 16;
for (int i = 0; i < 5; i++) {
ch = getchar();
while ((ch < '0' || ch > '9') && ch != '*') ch = getchar();
for (int j = 0; j < 5; j++)
if (ch == '1') num[i][j] = 1, ch = getchar();
else if (ch == '0') num[i][j] = 0, ch = getchar();
else num[i][j] = 2, ch = getchar(), s = i, e = j;
}
dfs(s, e, 0);
ans = ans == 16 ? -1 : ans;
printf("%d\n", ans);
}
}