在一个5×5的棋盘上有12个白色的骑士和12个黑色的骑士,且有一个空位。在任何时候一个骑士都能按照骑士的走法(它可以走到和它横坐标相差为1,纵坐标相差为2或者横坐标相差为2,纵坐标相差为1的格子)移动到空位上。给定一个初始的棋盘,怎样才能经过移动变成如下目标棋盘:为了体现出骑士精神,他们必须以最少的步数完成任务。
输入:
21011001*1110111010010000001011110*1011100101000100
输出:
7-1
思路
A*算法
#include#include #include #include using namespace std;char mp[5][6];int init[5][5]= {1,1,1,1,1, 0,1,1,1,1, 0,0,2,1,1, 0,0,0,0,1, 0,0,0,0,0 };int aim[5][5];int dirX[] = {1,1,-1,-1,2,2,-2,-2};int dirY[] = {2,-2,2,-2,1,-1,1,-1};int flag = 0,ans = 0;int cal() //估计接下来需要多少步{ int ans = 0; for(int i=0; i<5; i++) for(int j=0; j<5; j++) if(init[i][j]!=aim[i][j]) ans++; return ans;}void A_Star(int x,int y,int deep,int limit) { if(deep==limit) { if(!cal()) ans = deep; return ; } if(flag) return ; for(int i=0; i<8; i++) { int xx = x+dirX[i],yy = y+dirY[i]; if(xx<0||yy<0||xx>4||yy>4)continue; swap(init[x][y],init[xx][yy]); int G = cal(); if(G==0){flag = 1;} if(G+deep <= limit+1)A_Star(xx,yy,deep+1,limit); swap(init[x][y],init[xx][yy]); }}void solve(){ flag = 0; for(int i=0; i<5; i++) scanf("%s",mp[i]); int x,y; for(int i=0; i<5; i++) for(int j=0; j<5; j++) { if(mp[i][j]=='0')aim[i][j]=0; if(mp[i][j]=='1')aim[i][j]=1; if(mp[i][j]=='*')aim[i][j]=2,x=i,y=j; } for(int i=0; i<=15; i++) { if(!flag){ A_Star(2,2,0,i); if(flag)printf("%d\n",ans); } } if(flag==0)printf("%d\n",-1);}int main(){ int T; scanf("%d",&T); while(T--) solve(); return 0;}