• 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
    ",ans);
        }
        return 0;
    }
    
  • 相关阅读:
    hihocoder-1603-提取用户名
    hihocoder-1604-股票价格II
    求最长非重复子串
    程序员面试金典--取前K小的数
    hihocoder-1574-元素魔法--数学
    Struts2工作流程
    List和Map
    线程基本知识
    AOP通过反射机制实现动态代理/IOC依赖注入
    LayUi
  • 原文地址:https://www.cnblogs.com/fangbozhen/p/11766822.html
Copyright © 2020-2023  润新知