P1443 马的遍历(BFS广度优先搜索)

题目地址:P1443 马的遍历 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)

image

思路:

复读广度优先遍历的思路:

广度优先搜索算法的基本思想:
1、对于初始状态入队,设置初始状态为已访问。

2、如果队列不为空时,出队队头元素,否则跳到第五步。

3、检查出队的元素,检查所有相邻状态,如果有效且未访问,则将所有有效的相邻状态进行入队,并且设置这些状态为已访问,然后跳到第二部重复执行。

4、对于所有出队的元素,检查所有相邻状态,如果有效且未访问,则所有有效的相邻元素进行入队,并且设置这些状态为已访问,然后跳到第二步重复执行。

5、检查最后出队的元素是否为最终解,如果是输出结果,否则说明无解。

这里的马用的是中国象棋的马,可以走一个“日”字形的格子,即x增或减1,y增或减2或者x增或减2,y增或减1。假设马在一个无限大的格子的某一个位置上,此时马可以有八种走法:

image

此时只需把马可以走的位置依次入队计算即可。

样例解析:

初始状态,马能去这俩地方

image

这两匹马能去的有

image

以此类推即可。如果还不会可以自己画图。(懒得画了)

AC代码

#include <iostream>
#include <queue>
using namespace std;
int n, m, x, y;
int visited[405][405];//这里visited不仅拿来记录有无使用过,同时拿来记录几步可以到这里
int work[][3] = {{1,2},{2,1},{-1,2},{-2,1},{-1,-2},{1,-2},{2,-1},{-2,-1}};
//将八种的移动情况的坐标全部列举为数组方便使用
struct node
{
	int x, y;
	int step;
	//x,y是当前位置,step是当前步数
	node(int x_,int y_,int step_)
	{
		x = x_;
		y = y_;
		step = step_;
	}
	node()
	{
		step = -1;
	}
};
queue<node>q;
int main(int argc, char* argv[])
{
	cin >> n >> m >> x >> y;
	node a = node(x, y, 0);//从初始点开始入队遍历
	q.push(a);
	visited[x][y] = -2;//为了避免误判,随便把初始点设一个数字表示这个点用过了
	while (!q.empty())
	{
		node t = q.front();
		q.pop();
		for(int i=0;i<8;i++)
		{
			if((t.x+work[i][0]>=1&& t.y + work[i][1]>=1&& t.x + work[i][0] <= n&& t.y + work[i][1]<=m)&&!visited[t.x+work[i][0]][t.y+work[i][1]])
			{//判断八种情况能不能走,能则入队
				node temp = node(t.x + work[i][0], t.y + work[i][1], t.step + 1);
				q.push(temp);
				visited[t.x + work[i][0]][t.y + work[i][1]] = temp.step;
			}
		}
	}
	for(int i=1;i<=n;i++)
	{
		for(int j=1;j<=m;j++)
		{
			if (i == x && j == y)
			{//初始点是第零步就可以到达,所以直接输出0
				printf("%-5d", 0);
				continue;
			}
			if (!visited[i][j])
			{//到不了的是0,这里改成-1输出
				printf("%-5d", -1);
			}
			else
				printf("%-5d", visited[i][j]);
		}
		cout << endl;
	}
	return 0;
}

心得:

完全自己写了一次BFS,太久没敲代码十分生疏,想当初打前端的时候手速那个快阿。

posted @ 2022-01-11 21:31  张牧歌  阅读(83)  评论(0编辑  收藏  举报