本来是骑士跳,太多了,不如转换成空格跳。
现在位置合法:现在位置上的东西和目标状态这个位置上的东西一样。
现在位置不合法:现在位置上的东西和目标状态这个位置上的东西不一样。
四种情况:
空格要跳的位置的现在的骑士是合法的,和空格换了位置以后,不合法了;(原来空格所在位置上的目标骑士和空格要跳的位置上的现在骑士比较
空格要跳的位置现在的骑士是不合法的,和空格换了位置以后,合法了;(原来空格所在位置上的目标骑士和空格要跳的位置上的骑士比较
空格要跳的位置在目标状态中是空格的话,空格合法。
空格现在的位置在目标状态中是空格的话,跳走,空格不合法了。
he来记不合法的个数。
每次估计一下最少还要走多少步。如果当前步数+最少步数>规定步数则不合法。(迭代加深的思想
#include<iostream>
#include<cstdio>
using namespace std;
int b[7][7] ={
{0,0,0,0,0,0},
{0,1,1,1,1,1},
{0,0,1,1,1,1},
{0,0,0,-1,1,1},
{0,0,0,0,0,1},
{0,0,0,0,0,0}
};
int zl[9][2]= {{1,2},{2,1},{2,-1},{1,-2},{-1,2},{-2,1},{-2,-1},{-1,-2}};
int t,tp, a[7][7], cnt, cx, cy, ma, ans = 1e9;
char c[7][7];
int dfs(int x,int y,int shu,int fx,int s)
{
tp++;
if(shu + s > ma) return 0;
if(shu == 0){
return 1;
}
int haha = 0;
for(int i = 0; i <= 7; i++)
{
if(i == 7 - fx) continue;
int xx = x + zl[i][0];
int yy = y + zl[i][1];
if(xx >= 1 && xx <= 5 && yy >= 1 && yy <= 5)
{
int he = shu;
if(a[xx][yy] == b[xx][yy] && a[xx][yy] != b[x][y])he++;
if(a[xx][yy] != b[xx][yy] && a[xx][yy] == b[x][y]) he--;
if(b[xx][yy] == -1 ) he--;
if(b[x][y] == -1) he++;
int ttt = a[xx][yy];
a[xx][yy] = a[x][y];
a[x][y] = ttt;
haha = dfs(xx, yy, he, i, s +1);
if(haha == 1) return 1;
int tt = a[xx][yy];
a[xx][yy] = a[x][y];
a[x][y] = tt;
}
}
return 0;
}
int main()
{
scanf("%d",&t);
for(register int z = 1; z <= t; z++)
{
cnt = 0;
for(int i = 1; i <= 5; i++)
scanf("%s",c[i]+1);
for(int i = 1; i <= 5; i++)
for(int j = 1; j <= 5; j++)
{
if(c[i][j]== '*')
{
a[i][j] = -1; cx = i; cy = j;
}
else a[i][j] = c[i][j] - '0';
if(a[i][j] != b[i][j]) cnt++;
}
int ha = 0;
for(register int i = cnt; i <= 16; i++)
{
ma = i;
if(dfs(cx,cy,cnt,-1,0))
{
printf("%d\n",i - 1);
ha = 1;
break;
}
}
if(ha == 0) printf("-1\n");
}
return 0;
}