题目大意:给出一些黑白骑士的位置,问移动 11 步内是否能够得到目标位置。
解题思路:设置 tag 数组存下目标位置,每次移动都判断一次,然后就是回溯。剪枝只用了次数>10,可以再优化。一开始没转数字 , tag 是 char 型,移动判断什么的又用 int,总之 WA 了好几次,还是不要偷这种懒了(苦笑)另外注意骑士走的是日字,就是马的走法。
#include<iostream>
#include<cstdio>
#include<cmath>
#include<string.h>
#include<stdlib.h>
#include<algorithm>
using namespace std;
int tag[5][5]={{1,1,1,1,1},{0,1,1,1,1},{0,0,-1,1,1},{0,0,0,0,1},{0,0,0,0,0}};
int dx[] = {-2, -2, 2, 2, -1, 1, -1, 1};
int dy[] = {-1, 1, -1, 1, -2, -2, 2, 2};
int map[5][5];
char s[10];
bool ok() {
for (int i = 0; i < 5; i++)
for (int j = 0; j < 5; j++) {
if (tag[i][j] != map[i][j])
return false;
}
return true;
}
int ans;
bool flag;
void dfs(int n, int x, int y) {
if (ok()) {
if (n < ans) ans = n;
flag = true;
return;
}
if (n > 10) return;
for (int i = 0; i < 8; i++) {
int X = x + dx[i];
int Y = y + dy[i];
if (X < 0 || X > 4 || Y < 0 || Y > 4) continue;
int t = map[x][y];
map[x][y] = map[X][Y];
map[X][Y] = t;
dfs(n+1, X, Y);
map[X][Y] = map[x][y];
map[x][y] = t;
}
}
int main() {
int T, x, y;
scanf("%d", &T);
getchar();
while (T--) {
for (int i = 0; i < 5; i++) {
gets(s);
for (int j = 0; j < 5; j++)
if (s[j] == ' ') {
map[i][j] = -1;
x = i;
y = j;
}
else map[i][j] = s[j] - '0';
}
ans = 11;
flag = false;
dfs(0, x, y);
if (ans < 11) printf("Solvable in %d move(s).\n", ans);
else printf("Unsolvable in less than 11 move(s).\n");
}
return 0;
}
划水了一个多月,差点就放弃了 (´;ω;`)