ZOJ 1671 Walking Ant (BFS)

这是一篇关于ZOJ 1671题目的博客,讨论了在蚂蚁行走过程中如何处理可以重复路过某点的情况。关键在于,只有当蚂蚁再次路过某点时其HP值大于之前路过时的HP值,才会允许重复。此题目的解决策略涉及到了广度优先搜索(BFS)算法的变种应用。
摘要由CSDN通过智能技术生成

http://acm.zju.edu.cn/show_problem.php?pid=1671

该题与一般的BFS不同,它可以重复路过某点。因此如何判断可以重复路过某点呢?唯一的情况是路过该点的HP比以前路过该点时要大。

#include <iostream>
#include <vector>
#include <algorithm>
#include <queue>
#include <string.h>
#include <stdio.h>
using namespace std;

#define MAXINT 0x7FFFFFFF
#define Puddle 0
#define Nothing 1
#define Initial 2
#define Hole 3
#define Food 4

int dx[] = {0, 1, 0, -1};
int dy[] = {-1, 0, 1, 0};

int main()
{
	int w, h;
	int map[8][8];
	int cost[8][8];
	bool visited[8][8];
	int hp[8][8];
	while (cin >> w >> h && w > 0 && h > 0)
	{
		for (int i = 0; i < 8; i++)
			for (int j = 0; j < 8; j++)
			{
				map[i][j] = -1;
				cost[i][j] = MAXINT;
				visited[i][j] = false;
				hp[i][j] = 0;
			}
		for (int i = 0; i < h; i++)
			for (int j = 0; j < w; j++)
				cin >> map[i][j];

		queue< pair<int, int> > q;		
		for (int i = 0; i < h; i++)
			for (int j = 0; j < w; j++)
				if (map[i][j] == Initial)
				{
					q.push(make_pair<int, int>(i, j));
					cost[i][j] = 0;
					hp[i][j] = 6;
					break;
				}

		int time = -1;
		while (!q.empty())
		{
			int x = q.front().first;
			int y = q.front().second;
			q.pop();
			if (map[x][y] == Hole)
			{
				time = cost[x][y];
				break;
			}
			for (int i = 0; i < 4; i++)
				if (hp[x][y] > 1 &&
					(x + dx[i] >= 0 && x + dx[i] < h && y + dy[i] >= 0 && y + dy[i] < w) &&
					map[x + dx[i]][y + dy[i]] != Puddle &&
					(hp[x][y] - 1 > hp[x + dx[i]][y + dy[i]] && visited[x + dx[i]][y + dy[i]] == false))
				{
					q.push(make_pair<int, int>(x + dx[i], y + dy[i]));
					cost[x + dx[i]][y + dy[i]] = cost[x][y] + 1;
					if (map[x + dx[i]][y + dy[i]] == Food)
					{
						hp[x + dx[i]][y + dy[i]] = 6;
						visited[x + dx[i]][y + dy[i]] == true;
					}
					else
					{
						hp[x + dx[i]][y + dy[i]] = hp[x][y] - 1;
					}
				}
		}
		cout << time << endl;
	}
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值