【洛谷】2324:[SCOI2005]骑士精神【IDA*】

P2324 [SCOI2005]骑士精神

题目描述

输入输出格式

输入格式:

 

第一行有一个正整数T(T<=10),表示一共有N组数据。接下来有T个5×5的矩阵,0表示白色骑士,1表示黑色骑士,*表示空位。两组数据之间没有空行。

 

输出格式:

 

对于每组数据都输出一行。如果能在15步以内(包括15步)到达目标状态,则输出步数,否则输出-1。

 

输入输出样例

输入样例#1: 复制
2
10110
01*11
10111
01001
00000
01011
110*1
01110
01010
00100
输出样例#1: 复制
7
-1

说明


喜欢了!不枉我研究那么久搜索QAQ

不过还是卡了一会儿,因为在估价时不能算空格,空格是跟随别人走的。

然后就是迭代加深和A*的套路了...枚举最大深度,估价剪枝,然后直接暴力跳就行叻!

#include<bits/stdc++.h>
using namespace std;

int maxdep;

int zl[9][2] = {{2, 1}, {-2, 1}, {1, 2}, {-1, 2}, {1, -2}, {-1, -2}, {2, -1}, {-2, -1}};

int st[6][6], now[6][6], G[6][6];
char s[6][10];

void init() {
    for(int i = 1; i <= 5; i ++)
        for(int j = 1; j <= 5; j ++) {
            if(i <= 2 && j >= i)        st[i][j] = 1;
            else if(i <= 3 && j < 3)    st[i][j] = 0;
            else if(i == 3 && j == 3)    st[i][j] = 2;
            else if(i >= 4 && j <= i)    st[i][j] = 0;
            else st[i][j] = 1;
        }
}

bool check() {
    for(int i = 1; i <= 5; i ++)
        for(int j = 1; j <= 5; j ++) {
            if(now[i][j] != st[i][j])    return 0;
        }
    return 1;
}

int cot(int x, int y) {
    int num = 0;
    for(int i = 1; i <= 5; i ++)
        for(int j = 1; j <= 5; j ++)
            if(st[i][j] != now[i][j] && st[i][j] != 2)    num ++;
    return num;
}

bool pd(int x, int y) {
    if(x >= 1 && x <= 5 && y >= 1 && y <= 5)    return 1;
    return 0;
}

int fl, flag;
void dfs(int dep, int x, int y) {
    if(fl)    return ;
    if(dep == maxdep) {
        if(check()) fl = 1;
        return ;
    }
    if(dep + cot(x, y) > maxdep)    return ;
    for(int i = 0; i < 8; i ++) {
        int xx = x + zl[i][0], yy = y + zl[i][1];
        if(pd(xx, yy)) {
            swap(now[x][y], now[xx][yy]);
            dfs(dep + 1, xx, yy);
            if(fl)    return ;
            swap(now[x][y], now[xx][yy]);
        }
    }
    if(fl)    return ;
}

int main() {
    int T;
    scanf("%d\n", &T);
    init();
    while(T --) {
        int x, y;
        flag = 0;
        for(int i = 1; i <= 5; i ++) {
            scanf("%s", s[i] + 1);
        }
        for(int i = 1; i <= 5; i ++) {
            for(int j = 1; j <= 5; j ++) {
                if(s[i][j] == '1')    G[i][j] = 1;
                else if(s[i][j] == '0')    G[i][j] = 0;
                else G[i][j] = 2, x = i, y = j;
            }
        }
        for(maxdep = 0; maxdep <= 15; maxdep ++) {
            fl = 0;
            for(int i = 1; i <= 5; i ++)
                for(int j = 1; j <= 5; j ++)
                    now[i][j] = G[i][j];
            dfs(0, x, y);
            if(fl) {
                printf("%d\n", maxdep);    flag = 1;    break;
            }
        }
        if(!flag)    printf("-1\n");
    }
    return 0;
}

 

posted @ 2018-10-10 20:53  Wans_ovo  阅读(172)  评论(0编辑  收藏  举报