Knight Moves
Posted fangbozhen
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Knight Moves相关的知识,希望对你有一定的参考价值。
题目描述
在一个L×L的棋盘中,给出马的初始位置和终止位置,求最少跳多少步从初始到终止。
思路
bfs的模板题,不过为了提高速度我们可以采用双向宽度搜索,分别从起始位置和终止位置进行bfs,在判断何时两个bfs在同一地点相遇即可。为了避免效率过低,我们可以每次选择队列中节点少的进行拓展。
代码
#include <bits/stdc++.h> using namespace std; struct aa int x,y; st,ed; int dx[10]=1,1,-1,-1,2,2,-2,-2; int dy[10]=2,-2,2,-2,1,-1,1,-1; int dis[3][330][330],l,ans; queue<aa>q[3]; bool vis[3][330][330]; bool expand(int k) aa now=q[k].front();q[k].pop(); int d=dis[k][now.x][now.y]; for(int i=0;i<8;i++) aa nex; nex.x=now.x+dx[i];nex.y=now.y+dy[i]; if(nex.x<=0||nex.x>l||nex.y<=0||nex.y>l||vis[k][nex.x][nex.y]) continue ; vis[k][nex.x][nex.y]=1; dis[k][nex.x][nex.y]=d+1; q[k].push(nex); if(vis[1-k][nex.x][nex.y]) ans=dis[k][nex.x][nex.y]+dis[1-k][nex.x][nex.y]; return 1; return 0; void bfs() if(st.x==ed.x&&st.y==ed.y) ans=0;return ; vis[0][st.x][st.y]=1;q[0].push(st); vis[1][ed.x][ed.y]=1;q[1].push(ed); while(!q[0].empty()&&!q[1].empty()) if(q[0].size()<q[1].size()) if(expand(0))return ; if(q[1].size()<=q[0].size()) if(expand(1))return ; int main() int t; scanf("%d",&t); while(t--) while(!q[0].empty())q[0].pop(); while(!q[1].empty())q[1].pop(); memset(vis,0,sizeof(vis)); memset(dis,0,sizeof(dis)); scanf("%d",&l); scanf("%d%d%d%d",&st.x,&st.y,&ed.x,&ed.y); bfs(); printf("%d\n",ans); return 0;
以上是关于Knight Moves的主要内容,如果未能解决你的问题,请参考以下文章
Knight's tour backtrack 实现选择步长数组