马的遍历(BFS)-洛谷

洛谷-马的遍历

来源:https://www.luogu.com.cn/problem/P1443

题目描述

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

输入格式

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

输出格式

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

样例

输入

3 3 1 1

**输出 **

0    3    2    
3    -1   1    
2    1    4    

看到题目第一想法是~

1:马是怎么走的?哈哈哈哈哈。。。

“马”走动的方法是每步一直一斜,即先横着或直着走一格,然后再斜着走一个对角线,俗称“马走日”。在“日”的对角线上两点可以一步到达,其他地方不能到达,如图所示。

(x-2,y-1) (x-2,y+1)
(x-1,y-2) (x-1,y+2)
(x,y)马
(x+1,y-2) (x+1,y+2)
(x+2,y-1) (x+2,y+1)

2:左对齐,宽5格咋搞,百度即得 printf("%-5d",a);

3:然后想到了广度优先搜索,让我们先来解释一下这种搜索方式。

例如:这棵树

在这里插入图片描述

BFS搜索,假设从1开始,然后遍历和1相邻的2,3,4,接着通过2,3,4遍历5 6 7 8 9 10(注意顺序

实现过程是通过一个队列:(这里通过数组表示的队列)

1 2 3 4 5 6 7 8 9 10
1 2 3 4 5 6 7 8 9 10
1 2 3 4 5 6 7 8 9 10

当头指针等于尾指针时,遍历完毕,或者说符合条件的点,已经遍历完毕。

1 2 3 4 5 6 7 8 9 10
1 2 3 4 5 6 7 8 9 10
1 2 3 4 5 6 7 8 9 10

我们可以发现每一次的遍历都离原始点1是相同的距离,所以当我们做某些最短路径的题时候,可以考虑一下bfs。

先来一个模板:

BFS模板(广度优先搜索)

void bfs()
{
    
    
	 初始化,初始状态存数组; 
	 int head=0,tail=1,que[max_size];//构建队列
	 标记初始点 
	 while(head<tail)
	 {
    
    
	 	head++;//指向待扩展结点
		for(i=1;i<=maxi;++i)
		{
    
    
			if(满足条件||不重复)
			{
    
    
				tail++;
				将新节点存入队列
			}	
		}
	}
}
具体操作:

1:选择一个二维数组res[] [],先全部赋值为-1,里面存放到最终结果(棋盘上每一点的最短步数)

2: 用一个结构体数组a来表示马所在的位置,并充当BFS模板的队列,head,tail,充当队列的头尾指针

3:两个数组x[],y[]联合表示马可以到达的八个位置,用于判断是否符合条件,然后就是要注意在判断的时候不要越界就好啦。

然后是不是感觉来了,那就自己先试一试吧,万一就AC了呢。

完整代码:

 #include<bits/stdc++.h>
int n,m,nx,ny;  
int res[405][405];//res表示最终输出结果,下标代表棋盘位置,值代表最少步数 
int x[8]={
    
    1,2,-1,-2,-1,-2,1,2};
int y[8]={
    
    2,1,2,1,-2,-1,-2,-1};

struct queue{
    
    
	int x,y;
}a[40010];//构建bfs的队列(用数组表示) 

void bfs(int i,int j)
{
    
    
     int head=1,tail=2; 
     a[2].x=i,a[2].y=j;
	 res[i][j]=0;//初始位置的最少步数为0 
     while(head<tail)
	 {
    
    
        head++;
        for(int q=0;q<8;q++)
		{
    
    
			//(xx,yy)表示目前马走到的位置,还有。。。~~变量名真的好难取~~  
            int xx=a[head].x+x[q]; 
            int yy=a[head].y+y[q];
             
            if((res[xx][yy]==-1) && xx>=1 && xx<=n && yy>=1 && yy<=m)//判断是否走过,是否越界 
			{
    
    
                tail++;
                res[xx][yy]=res[a[head].x][a[head].y]+1;//最少步数加一 
                a[tail].x=xx;
                a[tail].y=yy;
            }
        }
    }
}

int main()
{
    
    
	
    scanf("%d%d%d%d",&n,&m,&nx,&ny);
    memset(res,-1,sizeof res);
    bfs(nx,ny);
    
    for(int i=1;i<=n;i++)
	{
    
    
        for(int j=1;j<=m;j++)
		{
    
    
			printf("%-5d",res[i][j]);
        }
        printf("\n");
    }
}

评测平台-洛谷
欢迎大家友好评论呀,有啥问题dd我呀。

猜你喜欢

转载自blog.csdn.net/m0_46288176/article/details/109257866
今日推荐