• 洛谷 P1443 马的遍历


    题目描述

    有一个n*m的棋盘(1<n,m<=400),在某个点上有一个马,要求你计算出马到达棋盘上任意一个点最少要走几步

    输入输出格式

    输入格式:

     

    一行四个数据,棋盘的大小和马的坐标

     

    输出格式:

     

    一个n*m的矩阵,代表马到达某个点最少要走几步(左对齐,宽5格,不能到达则输出-1)

    输入输出样例

    输入样例#1: 
    3 3 1 1
    
    输出样例#1: 
    0    3    2    
    3    -1   1    
    2    1    4   

    解题思路:
    本题数据较水,直接暴力bfs就AC了,先将全图答案初始化为-1,从起点开始,将起点入队列并更新答案为0.每次弹出队首元素,枚举队首元素可以走到的八个点,如果没有超出边界并且还没有得到最优解,就更新它的答案并将它入队列,循环下去,直到队列为空,输出答案即可.

    AC代码:
     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 int n,m,x,y,ans,a[405][405]; 
     4 int mx[8] = {2,-2,2,-2,-1,1,-1,1},my[8] = {1,1,-1,-1,2,2,-2,-2};//八个方向 
     5 bool vis[405][405];//储存每个点是否已经为最优答案 
     6 queue<int > q,q1;//q储存入队点行号,q1储存入队点列号 
     7 int main()
     8 {
     9     cin >> n >> m >> x >> y;
    10     memset(a,-1,sizeof(a));//将全图初始化为-1 
    11     q.push(x);
    12     q1.push(y);//起点入队 
    13     a[x][y] = 0;//更新起点答案 
    14     vis[x][y] = 1;//标记 
    15     while(!q.empty()) {
    16         int u = q.front();//弹出队首元素 
    17         int v = q1.front();//弹出队首元素 
    18         q.pop();q1.pop();
    19         for(int i = 0; i <= 7; i++) {//枚举八个点 
    20             int x1 = mx[i] + u; int y1 = my[i] + v;
    21             if(x1 >= 1 && x1 <= n && y1 >= 1 && y1 <= m && !vis[x1][y1]) {//解题思路过程 
    22                 a[x1][y1] = a[u][v] + 1;
    23                 vis[x1][y1] = 1;
    24                 q.push(x1);q1.push(y1);
    25             }
    26         }
    27     }
    28     for(int i=1;i<=n;i++)
    29     {
    30         for(int j=1;j<=m;j++)
    31         cout<<left<<setw(5)<<a[i][j];//题目要求左对齐,宽5格 
    32         cout<<endl;
    33     }
    34 return 0;
    35 }



  • 相关阅读:
    Oracle的建表约束
    Sql的增删改操作
    关联查询之92语法和99语法
    日常编程练习(三)
    日常编程练习(二)
    日常编程练习(一)
    C++ 赋值运算符函数
    内存管理
    进程同步——经典的同步问题
    I/O 阻塞与非阻塞,同步与异步
  • 原文地址:https://www.cnblogs.com/lipeiyi520/p/10355623.html
Copyright © 2020-2023  润新知