骑士精神(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; }