洛谷 P1443 马的遍历(bfs)

题目链接:https://www.luogu.org/problemnew/show/P1443
题意:一个n*m的棋盘,给你马的起始坐标,输出到达棋盘上每一点的最少步数,无法到达则输出-1
**思路:**bfs即可。
具体解释见代码:

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
using namespace std;
int n,m,x,y;//棋盘和马的初始坐标
int que[200001][4];//1,2是坐标,3是步数
int s[405][405];//到x,y的最少步数
int dx[8]={-2,-1,1,2,-2,-1,1,2};//方向数组
int dy[8]={-1,-2,-2,-1,1,2,2,1};
int main(){
    scanf("%d %d %d %d",&n,&m,&x,&y);//输入
    memset(s,-1,sizeof(s));//置为-1,无法到达也可以直接输出-1
    memset(que,0,sizeof(que));//清空
    que[1][1]=x;que[1][2]=y;//起始坐标入队
    s[x][y]=0;//初始坐标的步数为0
    int head=1,tail=1;//队头队尾
    while(head<=tail){//当还有元素在队内时
        for(int i=0;i<8;i++){
            int xx=que[head][1]+dx[i];
            int yy=que[head][2]+dy[i];
            if(xx>0&&yy>0&&xx<=n&&yy<=m){//在棋盘内
                if(s[xx][yy]==-1){//没有访问过
                    tail++;//队尾++
                    que[tail][1]=xx;//入队
                    que[tail][2]=yy;
                    s[xx][yy]=que[head][3]+1;
                    que[tail][3]=s[xx][yy];
                }
            }
        }
        head++;//队首++
    }
    for(int j,i=1;i<=n;i++){
        for(j=1;j<=m;j++){
            printf("%-5d",s[i][j]);//输出,注意题目要求,所以用-5d
        }
        printf("\n");
    }
return 0;
}

总结:bfs还是要勤加练习,特别是队列的应用。

猜你喜欢

转载自blog.csdn.net/yczhaoxun/article/details/79919358