题目描述:
在一个5×5的棋盘上有12个白色的骑士和12个黑色的骑士, 且有一个空位。在任何时候一个骑士都能按照骑
士的走法(它可以走到和它横坐标相差为1,纵坐标相差为2或者横坐标相差为2,纵坐标相差为1的格子)移动到空
位上。 给定一个初始的棋盘,怎样才能经过移动变成如下目标棋盘: 为了体现出骑士精神,他们必须以最少的步
数完成任务。
题解:
IDA*
搜索。
非常友好。
代码:
#include<cstdio> #include<cstring> #include<algorithm> using namespace std; int T; char ch[7]; int a[7][7],b[7][7]={{0,0,0,0,0},{0,1,1,1,1,1},{0,0,1,1,1,1},{0,0,0,2,1,1},{0,0,0,0,0,1}}; int h(int a0[7][7]) { int ret = 0; for(int i=1;i<=5;i++) for(int j=1;j<=5;j++) ret+=(a0[i][j]!=b[i][j]); return ret; } bool judge(int a0[7][7]) { for(int i=1;i<=5;i++) for(int j=1;j<=5;j++) if(a0[i][j]!=b[i][j]) return 0; return 1; } int ans,lim; int dx[]={-2,2,-1,1,-1,1,-2,2}; int dy[]={-1,1,-2,2,2,-2,1,-1}; bool check(int x,int y) { return x>=1&&x<=5&&y>=1&&y<=5; } void dfs(int a0[7][7],int dep,int x,int y) { if(dep>lim) { if(judge(a0))ans=lim; return ; } if(~ans)return ; for(int i=0;i<8;i++) { int xx = x+dx[i],yy = y+dy[i]; if(!check(xx,yy))continue; swap(a0[x][y],a0[xx][yy]); if(h(a0)+dep-1<=lim)dfs(a0,dep+1,xx,yy); swap(a0[x][y],a0[xx][yy]); } } int main() { // freopen("tt.in","r",stdin); scanf("%d",&T); while(T--) { ans=-1; int x,y; for(int i=1;i<=5;i++) { scanf("%s",ch+1); for(int j=1;j<=5;j++) { if(ch[j]==‘*‘)a[i][j]=2,x=i,y=j; else a[i][j]=ch[j]-‘0‘; } } for(lim=1;lim<=15;lim++) { dfs(a,1,x,y); if(~ans)break; } printf("%d\n",ans); } return 0; }
原文地址:https://www.cnblogs.com/LiGuanlin1124/p/10009200.html
时间: 2024-10-18 13:48:23