题意:类似与八数码,不过限制了最大步数为10。
用了DFS回溯,有点慢。还可以用BFS+HASH
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
using namespace std;
const int N = 5;
int s[N][N];
int ans;
int dir[8][2] = { {-2, -1}, {-2, 1}, {-1, 2}, {1, 2}, {2, 1}, {2, -1}, {1, -2}, {-1, -2} };
int target[N][N] = {{1,1,1,1,1}, {0,1,1,1,1}, {0,0,-1,1,1},{0,0,0,0,1},{0,0,0,0,0}};
bool check()
{
//for(int i = 0; i < N; i++)
// for(int j = 0; j < N; j++)
// if(s[i][j] != target[i][j])
// return false;
//return true;
return !memcmp(s, target, sizeof(target));
}
void dfs(int x, int y, int cur)
{
if(cur > 10 || cur >= ans)
return ;
if(check())
{
ans = cur;
return;
}
else if(cur == 10)
return;
for(int i = 0; i < 8; i++)
{
int nx = x+dir[i][0], ny = y + dir[i][1];
if(0<=nx&&nx<N && 0<=ny&&ny<N)
{
swap(s[nx][ny], s[x][y]);
dfs(nx, ny, cur+1);
swap(s[nx][ny], s[x][y]);
}
}
}
int main()
{
//freopen("in.txt", "r", stdin);
int cas;
scanf("%d", &cas);
getchar();
while(cas--)
{
int x, y;
for(int i = 0; i < N; i++)
{
for(int j = 0; j < N; j++)
{
int t = getchar();
if(t != ' ')
{
s[i][j] = t - '0';
}
else
{
s[i][j] = -1;
x = i;
y = j;
}
}
getchar();
}
ans = 0x3f3f3f3f;
dfs(x, y, 0);
if(ans <= 10)
printf("Solvable in %d move(s).\n", ans);
else
printf("Unsolvable in less than 11 move(s).\n");
}
return 0;
}