经典的棋盘类问题,移动骑士到达指定状态,最少要几次,如果超过10次则输出Unsolvable in less than 11 move(s).
一开始想bfs的,但是状态量比较大,又懒得写hash,又想到了最坏情况,也就是超出10次时,dfs和bfs复杂度都一样,于是就果断用了ID+dfs,编程难度非常低。
不用加剪枝就可以过了,我的代码里加了个最优下限,这样不用每次从0开始进行ID,刚有想到可以利用当前最优情况进行可行性剪枝,但要睡觉了就不再优化了。
/* author:jxy lang:C/C++ university:China,Xidian University **If you need to reprint,please indicate the source** */ #include <iostream> #include <cstdio> #include <cstdlib> #include <cstring> #include <queue> #define INF 1E9 using namespace std; const int dir[8][2]={-2,-1,-1,-2,1,-2,2,-1,-2,1,-1,2,1,2,2,1}; const string aim="111110111100 110000100000"; char s[26]; char now[6][6]; int dfs(int depth,string s) { if(s==aim)return 1; if(depth==0)return 0; int i,j,m,k=0,x,y,tx,ty; for(i=0;i<5;i++ ) for(j=0;j<5;j++) { if(s[k]==' '){x=j,y=i;} now[i][j]=s[k++]; } for(i=0;i<8;i++) { tx=x+dir[i][0];ty=y+dir[i][1]; if(tx<0||tx>4||ty<0||ty>4)continue; swap(now[ty][tx],now[y][x]); for(m=0,k=0;m<5;m++) for(j=0;j<5;j++) s[k++]=now[m][j]; if(dfs(depth-1,s))return 1; swap(now[ty][tx],now[y][x]); } return 0; } int main() { int T,i,j,k; scanf("%d",&T); while(T--) { int Min=0;//确定最优情况 for(i=0,k=0;i<5;i++) { getchar(); for(j=0;j<5;j++) { s[k++]=getchar(); Min+=(s[k-1]!=aim[k-1]); } } s[k]='\0'; for(i=Min/2;i<11&&!dfs(i,s);i++); if(i<11)printf("Solvable in %d move(s).\n",i); else printf("Unsolvable in less than 11 move(s).\n"); } }