传送门:http://www.lydsy.com:808/JudgeOnline/problem.php?id=1085
裸的迭代加深搜索,关于剪枝,我设计了一个估价函数h()表示当前状态与目标状态不一样的对应位置的个数减1,为什么大家都懂吧。
速度不算快,但对于如此简单的剪枝来说已经不错了。
#include <iostream> #include <cstdio> #include <cstring> using namespace std; const int maxn = 6; char a[maxn][maxn]; char b[maxn][maxn] = {"11111", "01111", "00*11", "00001", "00000"}; int dd[8][2] = {{1, 2}, {2, 1}, {1, -2}, {-2, 1}, {-1, 2}, {2, -1}, {-1, -2}, {-2, -1}}; int t, dep; bool jd() { for(int i = 0; i < 5; i ++) { for(int j = 0; j < 5; j ++) { if(a[i][j] != b[i][j]) return false; } } return true; } int calc() { int res = 0; for(int i = 0; i < 5; i ++) { for(int j = 0; j < 5; j ++) { if(a[i][j] != b[i][j]) res ++; } } return res - 1; } bool check(int x, int y) { if(x < 0 || y < 0 || x >= 5 || y >= 5) return false; return true; } bool dfs(int d, int px, int py) { if(d > dep) { if(jd()) return true; return false; } if(calc() + d - 1 > dep) return false; for(int i = 0; i < 8; i ++) { int tx = px + dd[i][0]; int ty = py + dd[i][1]; if(check(tx, ty)) { swap(a[px][py], a[tx][ty]); if(dfs(d + 1, tx, ty)) return true; swap(a[px][py], a[tx][ty]); } } return false; } int main() { scanf("%d", &t); while(t --) { int px, py; for(int i = 0; i < 5; i ++) { scanf("%s", a[i]); for(int j = 0; j < 5; j ++) { if(a[i][j] == '*') { px = i; py = j; } } } dep = 0; while(dep <= 15 && !dfs(1, px, py)) dep ++; if(dep > 15) printf("-1\n"); else printf("%d\n", dep); } return 0; }