• A


    A - 移动的骑士

    Time Limit: 1000/1000MS (C++/Others) Memory Limit: 65536/65536KB (C++/Others)

    Problem Description

    Somurolov先生是一个国际象棋高手,他声称在棋盘上将骑士棋子从一点移动到另外一点,没有人比他快,你敢挑战他吗?
    你的任务是编程计算出将一个骑士棋子从一点移动到另外一点,最少需要移动的步数。显而易见,这样你就有赢得Somurolov先生的机会。国际象棋中的骑士在棋盘上可移动的范围如下图:

    Input

    首先输入测试样例的个数n。接下来是n组输入数据,每组测试数据由三行整数组成:第一行是棋盘的边长l (4 <= l <= 300),整个棋盘的面积也就是 l*l;第二行和第三行分别是骑士棋子的初始位置和目标位置,表示为整数对形式{0, …, l-1}*{0, …, l-1}。保证棋子的初始和目标位置是棋盘上的合法位置。

    Output

    对于每一个输入的测试样例,请你算出骑士从初始位置移动到目标位置最小移动步数。如果初始位置和目标位置相同,那么骑士移动的距离就是0。最后单独一行输出所求距离。

    Sample Input

    3
    8
    0 0
    7 0
    100
    0 0
    30 50
    10
    1 1
    1 1

    Sample Output

    5
    28
    0




    #include<cstdio>
    #include<cstring>
    #include<queue>
    using namespace std;
    
    const int maxn = 305;
    
    bool mp[maxn][maxn]; // 表示当前点是否被走过
    int sx, sy, tx, ty, l; // s表示初始坐标,t表示目标位置
    int tox[] = {1, 2, 2, 1, -1, -2, -2, -1};
    int toy[] = {2, 1, -1, -2, -2, -1, 1, 2};
    // 通过下标关联,表示马的八个走向
    
    struct Node { // 结构体,表示当前点的坐标和到达步数
        int x, y, s;
    };
    
    bool judge(Node n){ // 用于判断一个坐标(x, y)是否在图内,并且没有被走过
        if(n.x >=0 && n.x < l && n.y >= 0 
            && n.y < l && !mp[n.x][n.y]) return true;
        return false;
    }
    
    int bfs(){
        Node now, nxt;
        queue<Node > q;
        now.x = sx;
        now.y = sy;
        now.s = 0;   // 起始点的初始化
        q.push(now); // 将起始点加入队列
        mp[now.x][now.y] = true; // 起始点已经走过了
        while(!q.empty()){
            now = q.front();
            q.pop();
    
            if(now.x == tx && now.y == ty) return now.s; //到达目标点
            for(int i=0; i<8; i++){ // 枚举马的八种走法
                nxt.x = now.x + tox[i];
                nxt.y = now.y + toy[i];
                nxt.s = now.s + 1;
    
                if(judge(nxt)){ // 下一个位置在图内且可以走
                    q.push(nxt); // 加入队列
                    mp[nxt.x][nxt.y] = true;
                }
            }
        }
        return -1;
    }
    
    int main()
    {
        int n;
        scanf("%d", &n);
        while(n--){
            memset(mp, false, sizeof(mp));
            scanf("%d", &l);
            scanf("%d%d", &sx, &sy);
            scanf("%d%d", &tx, &ty);
            int ans = bfs();
    
            printf("%d
    ", ans);
        }
    
        return 0;
    }
  • 相关阅读:
    实现treeview的动态加载
    sql server2000中使用convert来取得datetime数据类型样式(全)
    一道微软公司的面试题目的算法实现
    后台一行输入太多内容,使前台显示自动换行方法
    在js中刷新本页
    关于datediff函数的用法
    C#中StringBuilder类的使用(转)
    在字符串中使用引号("")等字符 需要用转义字符\ 例如
    常用的SQL和TSQL语句(一) (转)
    JS弹出窗口的运用与技巧(转)
  • 原文地址:https://www.cnblogs.com/yangf428/p/10180757.html
Copyright © 2020-2023  润新知