Knight Moves

Posted fangbozhen

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Knight Moves相关的知识,希望对你有一定的参考价值。

https://loj.ac/problem/10028

题目描述

  在一个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-回溯(无法解决奇怪的棋盘尺寸)

Knight's Tour C++ 使用堆栈

ural 1197. Lonesome Knight

Knight's tour backtrack 实现选择步长数组

LeetCode Knight Probability in Chessboard

D - Knight Tournament