1085: [SCOI2005]骑士精神
IDA*
A*部分:每次判断当前使用步数和至少还需步数的和是否满足当前解;
#include <iostream> #include <algorithm> #include <cstdio> #include <cstring> using namespace std; int T, dep; bool esp; bool tgt[6][6] = { {1,1,1,1,1}, {0,1,1,1,1}, {0,0,0,1,1}, {0,0,0,0,1}, {0,0,0,0,0} }; int dir[8][2] = { 1,2,1,-2,-1,2,-1,-2,2,1,2,-1,-2,1,-2,-1 }; bool judge(bool nmp[6][6], int x, int y) { if (x != 2 || y != 2) return false; for (int i = 0; i < 5; ++i) { for (int j = 0; j < 5; ++j) if (nmp[i][j] != tgt[i][j]) return false; } return true; } int minstep(bool nmp[6][6], int step) { int otherstep = 0; for (int i = 0; i < 5; ++i) { for (int j = 0; j < 5; ++j) if (nmp[i][j] != tgt[i][j]) otherstep ++; if (otherstep + step > dep) return false; } return true; } void dfs(int step, bool nmp[6][6], int x, int y) { if (step == dep) { if (judge(nmp, x, y)) esp = true; return ; } if (esp) return ; for (int i = 0; i < 8; ++i) { int nx = x + dir[i][0]; int ny = y + dir[i][1]; if (nx < 0 || nx >= 5 || ny < 0 || ny >= 5) continue; swap(nmp[x][y], nmp[nx][ny]); if (minstep(nmp, step)) dfs(step+1, nmp, nx, ny); swap(nmp[x][y], nmp[nx][ny]); } } int main() { scanf("%d", &T); for (int cas = 1; cas <= T; ++cas) { esp = false; bool nmp[6][6]; memset(nmp, 0, sizeof(nmp)); int x, y; for (int i = 0; i < 5; ++i) { char c[7]; scanf("%s", c); for (int j = 0; j < 5; ++j) { if (c[j] == '*') {x = i, y = j;} else nmp[i][j] = c[j] - '0'; } } for (dep = 1; dep <= 15; ++dep) { dfs(0, nmp, x, y); if (esp) { printf("%d\n", dep); break; } } if (!esp) printf("-1\n"); } return 0; }

浙公网安备 33010602011771号