在一个5×5的棋盘上有12个白色的骑士和12个黑色的骑士, 且有一个空位。在任何时候一个骑士都能按照骑士的走法(它可以走到和它横坐标相差为1,纵坐标相差为2或者横坐标相差为2,纵坐标相差为1的格子)移动到空位上。 给定一个初始的棋盘,怎样才能经过移动变成如下目标棋盘: 为了体现出骑士精神,他们必须以最少的步数完成任务。
在一个5×5的棋盘上有12个白色的骑士和12个黑色的骑士, 且有一个空位。在任何时候一个骑士都能按照骑士的走法(它可以走到和它横坐标相差为1,纵坐标相差为2或者横坐标相差为2,纵坐标相差为1的格子)移动到空位上。 给定一个初始的棋盘,怎样才能经过移动变成如下目标棋盘: 为了体现出骑士精神,他们必须以最少的步数完成任务。
第一行有一个正整数T(T<=10),表示一共有N组数据。接下来有T个5×5的矩阵,0表示白色骑士,1表示黑色骑士,*表示空位。两组数据之间没有空行。
对于每组数据都输出一行。如果能在15步以内(包括15步)到达目标状态,则输出步数,否则输出-1。
1 #include<cstdio> 2 #include<algorithm> 3 using namespace std; 4 const int mb[5][5]={{1,1,1,1,1}, 5 {0,1,1,1,1}, 6 {0,0,2,1,1}, 7 {0,0,0,0,1}, 8 {0,0,0,0,0}}; 9 int fx[8]={1,1,-1,-1,2,2,-2,-2}; 10 int fy[8]={2,-2,2,-2,1,-1,1,-1}; 11 int map[5][5],ans,T; 12 char ch[10]; 13 bool pd(int map[5][5],int s){ 14 int v=0; 15 for(int i=0;i<5;i++) for(int j=0;j<5;j++) if(map[i][j]!=mb[i][j]){ 16 v++;if(v+s>ans) return 0; 17 } 18 return 1; 19 } 20 21 bool ok(int map[5][5]){ 22 for(int i=0;i<5;i++) 23 for(int j=0;j<5;j++) 24 if(map[i][j]!=mb[i][j])return 0; 25 return 1; 26 } 27 28 void dfs(int x,int y,int s){ 29 if (s>ans) return; 30 if(ok(map)) {if(s<ans) ans=s; return;} 31 for(int i=0;i<8;i++){ 32 int nx=x+fx[i],ny=y+fy[i]; 33 if(nx>=5||nx<0||ny>=5||ny<0) continue; 34 swap(map[x][y],map[nx][ny]); 35 if(pd(map,s)) 36 dfs(nx,ny,s+1); 37 swap(map[x][y],map[nx][ny]); 38 } 39 } 40 int main(){ 41 scanf("%d",&T); 42 while(T--){ 43 ans=16;int x,y; 44 for(int i=0;i<5;i++){ 45 scanf("%s",ch); 46 for(int j=0;j<5;j++){ 47 if(ch[j]=='*') map[i][j]=2,x=i,y=j; 48 else map[i][j]=ch[j]-'0'; 49 } 50 } 51 dfs(x,y,0); 52 if(ans==16) printf("-1\n");else printf("%d\n",ans); 53 } 54 }