#113-【广搜】青铜莲花池

在农夫约翰建造的池塘中,贝西正练习芭蕾舞,目标是从一朵莲花跳到另一朵莲花。遵循象棋中马的移动规则,贝西需找到从起点到终点的最短路径。通过广度优先搜索算法,可以高效解决这一路径寻找问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目描述

为了让奶牛们娱乐和锻炼,农夫约翰建造了一个美丽的池塘。这个长方形的池子被分成了M行N列个方格(1 ≤ M, N ≤30)。一些格子是坚固得令人惊讶的莲花,还有一些格子是岩石,其余的只是美丽、纯净、湛蓝的水。

贝西正在练习芭蕾舞,她站在一朵莲花上,想跳到另一朵莲花上去,她只能从一朵莲花跳到另一朵莲花上,既不能跳到水里,也不能跳到岩石上。

贝西的舞步很像象棋中的马步:每次总是先横向移动M1 (1 ≤ M1 ≤ 30)格,再纵向移动M2 (1 ≤ M2 ≤ 30, M1     M2)格,或先纵向移动M1格,再横向移动M2格。最多时,贝西会有八个移动方向可供选择。

给定池塘的布局和贝西的跳跃长度,请计算贝西从起点出发,到达目的地的最小步数,我们保证输入数据中的目的地一定是可达的。

输入

第一行:四个用空格分开的整数:M,N,M1和M2

第二行到M + 1行:第i + 1行有N个用空格分开的整数,描述了池塘第i行的状态:0 为水,1 为莲花,2 为岩石,3 为贝西所在的起点,4 为贝西想去的终点。

输出

第一行:从起点到终点的最少步数

样例输入

4 5 1 2 
1 0 1 0 1 
3 0 2 0 4 
0 1 2 0 0 
0 0 0 1 0 

样例输出

2

提示

样例解释:贝西从第二行的最左边出发,目标是第二行的最右边。贝西先跳到第一行第三列的莲花上,再跳到终点,需要两步。

来源

广搜 

基本BFS,不用多说。

#include <iostream>
#include <queue>

#define SIZE 110

using namespace std;

struct node
{
	int x, y, dis;
};

queue<node> q;
int a[SIZE][SIZE], dx[8], dy[8];

int main(void)
{
	int n, m, i, j, x, y, r, c, sx, sy;
	
	scanf("%d%d%d%d", &n, &m, &x, &y);
	for (i = 1; i <= n; ++i) // 输入
	{
		for (j = 1; j <= m; ++j)
		{
			scanf("%d", &a[i][j]);
			if (a[i][j] == 3)
			{
				sx = i;
				sy = j;
			}
		}
	}
	
	dx[0] = -y; // 前进方向
	dy[0] = -x;
	dx[1] = x;
	dy[1] = y;
	dx[2] = x;
	dy[2] = -y;
	dx[3] = -x;
	dy[3] = y;
	dx[4] = -x;
	dy[4] = -y;
	dx[5] = y;
	dy[5] = x;
	dx[6] = y;
	dy[6] = -x;
	dx[7] = -y;
	dy[7] = x;
	q.push({sx, sy, 0});
	while (!q.empty()) // BFS模板
	{
		x = q.front().x;
		y = q.front().y;
		for (i = 0; i < 8; ++i)
		{
			r = x + dx[i];
			c = y + dy[i];
			if (a[r][c] == 4)
			{
				printf("%d", q.front().dis + 1); // 到达终点,输出步数
				return 0;
			}
			if (a[r][c] == 1)
			{
				a[r][c] = 0;
				q.push({r, c, q.front().dis + 1});
			}
		}
		q.pop();
	}
	
	return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值