传送门: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;
}