骑士精神(IDA*)

题目描述

输入格式

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

输出格式

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


emmmmmm, 一道机房各位强者都A掉的题, IDA* = 迭代加深DFS + 估价函数。 用当前的状态与目标状态不同的点数作为估价函数, 以步数为迭代的深度, 在合法的情况下进行dfs, 最终输出答案

 

#include <bits/stdc++.h>

using namespace std;

typedef long long ll;
const int INF = 0x3f3f3f3f;
const int MAXN = 5e5 + 100;
const int MAXM = 3e3 + 10;

template < typename T > inline void read(T &x) {
    x = 0; T ff = 1, ch = getchar();
    while(!isdigit(ch)) {
        if(ch == '-') ff = -1;
        ch = getchar();
    } 
    while(isdigit(ch)) {
        x = (x << 1) + (x << 3) + (ch ^ 48);
        ch = getchar();
    } 
    x *=ff;
} 

template < typename T > inline void write(T x) {
    if(x < 0) putchar('-'), x = -x;
    if(x > 9) write(x / 10); 
    putchar(x % 10 + '0'); 
} 

int T, u, v, flag = false;
int a[10][10];
int dx[10] = {2, 1, 2, 1, -2, -1, -2, -1};
int dy[10] = {1, 2, -1, -2, 1, 2, -1 ,-2};
int b[10][10] = {
    {3, 3, 3 ,3, 3, 3}, 
    {3, 1, 1, 1, 1, 1}, 
    {3, 0, 1, 1, 1, 1},
    {3, 0, 0, 2, 1, 1}, 
    {3, 0, 0, 0, 0, 1},
    {3, 0, 0, 0, 0, 0},
};
char ch;

int get_H() {
    int cnt = 0;
    for(int i = 1; i <= 5; ++i) {
        for(int j = 1; j <= 5; ++j)
            if(a[i][j] != b[i][j]) ++cnt;
    }
    return cnt;
}

void IDAstar(int now, int high, int x, int y) {
    if(now == high) {
        if(!get_H()) {
            flag = true;
            return ;
        } 
    }
    for(int i = 0; i < 8; ++i) {
        int xx = x + dx[i], yy = y + dy[i];
        if(xx < 1 || xx > 5 || yy < 1 || yy > 5) continue;
        swap(a[xx][yy], a[x][y]);
        if(now + get_H() - 1 < high) 
            IDAstar(now + 1, high, xx, yy);
        swap(a[x][y], a[xx][yy]);
    }
}

int main() {
    read(T);
    while(T--) {
        for(int i = 1; i <= 5; ++i) {
            for(int j = 1; j <= 5; ++j) {
                cin >> ch;
                if(ch == '*') {
                    a[i][j] = 2;
                    u = i;
                    v = j;
                }
                else a[i][j] = (ch - '0');
            } 
        }
        if(!get_H()) {
            puts("0");
            continue;
        }
        flag = false;
        for(int i = 1; i <= 15; ++i) {
            IDAstar(0, i, u, v);
            if(flag) {
                write(i);
                puts("");
                break;
            }
        }
        if(!flag) puts("-1");
    }
    
    return 0;
} 

 

posted @ 2019-09-06 13:48  海边微风起  阅读(270)  评论(0编辑  收藏  举报