鸣人和佐助 非三维数组解法

题目:

鸣人和佐助 - OpenJ_Bailian 4115 - Virtual Judge (vjudge.net)

题面:

分析:

与正常BFS不同的是,会重复走之前已经 visit 的路径,所以只用一个 数组来标记是否走过 来剪枝的做法不行

那么我们的剪枝条件就在于查克拉

查克拉是逐渐减少的,最小为0

为了避免走重复无效的路,下一步所在位置的查克拉需要小于当前的(查克拉数组初始为-1)

不等于是因为避免往回走

代码:

/*
Problem: https://vjudge.net/problem/OpenJ_Bailian-4115

*/

#include <iostream>
#include <cstring>
#include <queue>
using namespace std;
const int N = 210;

struct Node // 存每个点的信息
{
	int x, y, all, t; // 坐标,用时,查克拉
};

int check[N][N]; // 当前坐标的查克拉

char g[N][N];
int n, m, T;
int dx[] = { 0,0,-1,1 }, dy[] = { 1,-1,0,0 };

queue<Node> q;
int bfs()
{
	memset(check, -1, sizeof check);
	while (!q.empty())
	{
		Node tmp = q.front();
		q.pop();
		for (int i = 0; i < 4; i++)
		{

			int x = tmp.x + dx[i], y = tmp.y + dy[i];
			int c = tmp.t;
			int step = tmp.all;

			if (g[x][y] == '+') return step + 1;

			if (x >= 0 && x < n && y >= 0 && y < m && check[x][y] < c) 
				// 如果当前查克拉大于等于上一步的,则不走
			{
				if (g[x][y] == '#')
				{
					if (c > 0) // 有查克拉剩余
					{
						check[x][y] = c - 1;
						q.push({ x,y,step + 1, c - 1 });
					}
					continue; // 无查克拉剩余直接返回
				}
				check[x][y] = c;
				q.push({ x,y,step + 1, c }); // 没走到 # 查克拉不减少
			}
		}
	}
	return -1;
}



int main()
{
	(cin >> n >> m >> T).get();
	for (int i = 0; i < n; i++)
	{
		for (int j = 0; j < m; j++)
		{
			cin >> g[i][j];
			if (g[i][j] == '@')
			{
				check[i][j] = T;
				q.push({ i,j,0,T });
			}
		}
		cin.get();
	}

	cout << bfs() << endl;
	return 0;
}

收获:

很多博客都用的三维数组,感觉那实在过于繁琐,参考了别人的思路才整了个check数组

用结构体来保存坐标比用pair保存坐标更加简洁些,能把附加信息直接绑定上

check数组的话没法绑定,需要提前获取下一步的信息

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值