IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 游戏开发 -> 杭电oj1072Nightmare(带注释和思路)(bfs) -> 正文阅读

[游戏开发]杭电oj1072Nightmare(带注释和思路)(bfs)

Problem Description

Ignatius had a nightmare last night. He found himself in a labyrinth with a time bomb on him. The labyrinth has an exit, Ignatius should get out of the labyrinth before the bomb explodes. The initial exploding time of the bomb is set to 6 minutes. To prevent the bomb from exploding by shake, Ignatius had to move slowly, that is to move from one area to the nearest area(that is, if Ignatius stands on (x,y) now, he could only on (x+1,y), (x-1,y), (x,y+1), or (x,y-1) in the next minute) takes him 1 minute. Some area in the labyrinth contains a Bomb-Reset-Equipment. They could reset the exploding time to 6 minutes.

Given the layout of the labyrinth and Ignatius’ start position, please tell Ignatius whether he could get out of the labyrinth, if he could, output the minimum time that he has to use to find the exit of the labyrinth, else output -1.

Here are some rules:

  1. We can assume the labyrinth is a 2 array.
  2. Each minute, Ignatius could only get to one of the nearest area, and he should not walk out of the border, of course he could not walk on a wall, too.
  3. If Ignatius get to the exit when the exploding time turns to 0, he can’t get out of the labyrinth.
  4. If Ignatius get to the area which contains Bomb-Rest-Equipment when the exploding time turns to 0, he can’t use the equipment to reset the bomb.
  5. A Bomb-Reset-Equipment can be used as many times as you wish, if it is needed, Ignatius can get to any areas in the labyrinth as many times as you wish.
  6. The time to reset the exploding time can be ignore, in other words, if Ignatius get to an area which contain Bomb-Rest-Equipment, and the exploding time is larger than 0, the exploding time would be reset to 6.

Input

The input contains several test cases. The first line of the input is a single integer T which is the number of test cases. T test cases follow.
Each test case starts with two integers N and M(1<=N,Mm=8) which indicate the size of the labyrinth. Then N lines follow, each line contains M integers. The array indicates the layout of the labyrinth.
There are five integers which indicate the different type of area in the labyrinth:
0: The area is a wall, Ignatius should not walk on it.
1: The area contains nothing, Ignatius can walk on it.
2: Ignatius’ start position, Ignatius starts his escape from this position.
3: The exit of the labyrinth, Ignatius’ target position.
4: The area contains a Bomb-Reset-Equipment, Ignatius can delay the exploding time by walking to these areas.

Output

For each test case, if Ignatius can get out of the labyrinth, you should output the minimum time he needs, else you should just output -1.

Sample Input

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

Sample Output

4
-1
13

思路

1.

运用广度优先遍历(bfs),可求得最小的走的路程

2.

从队列中提取出数据后,要将其往四个方向进行移动,不符合条件不用处理,符合条件(不是休息设备)则步数+1,时间+1,符合条件(休息设备)则步数+1,时间清零。然后将当前符合条件的情况入列

3.

经过几次试验后,发现有些最佳情况是需要多次经过普通路径的,但不会多次经过休息设备,所以我们可以将休息设备设置一个visit数组,经过后就不能再经过,这样当休息设备有限时,就不会出现反复横跳的情况(因为时间总会到)。

ps:

写完发现当经过休息设备后,其实可以将休息设备对应的数字4直接改成0可能会更简单些

代码

#include<iostream>
#include<cstdio>
#include<cmath>
#include<string>
#include<algorithm>
#include<set>
#include<iomanip>
#include<queue>
#include<stack>
typedef long long l;
using namespace std;
int M = INT_MAX;
int map[9][9];
int visit[9][9] = { 0 };
int fx[4][2] = { 1,0,-1,0,0,1,0,-1 };
int ti = 0;
bool arr = false;
int a, b, x1, y11, x2, y2;
struct point//点
{
	int x, y, step, time;
};
int bfs()
{
	queue<point> q;
	point p;
	p.x = x1;
	p.y = y11;
	p.step = 0;
	p.time = 0;
	q.push(p);
	while (!q.empty())
	{
		point p = q.front();//出列
		q.pop();
		if (p.x == x2 && p.y == y2 && p.time <= 5)//刚出队列就判断是否符合
			return p.step;
		if (p.time >= 5)continue;//刚出队列就判断是否超时
		for (int i = 0; i < 4; i++)//分别向四个方向
		{
			point t;
			t.x = p.x + fx[i][0];
			t.y = p.y + fx[i][1];//更新目前x\y坐标
			t.step = p.step + 1;//步数+1
			if (t.x < 0 || t.x >= a || t.y < 0 || t.y >= b)continue;//范围错误
			if (map[t.x][t.y] == 0)continue;//墙
			if (map[t.x][t.y] == 4)//补给站
			{
				if (visit[t.x][t.y])continue;
				else {
					visit[t.x][t.y] = 1;//表示已被访问
					t.time = 0;//时间清零
					q.push(t);
					continue;
				}
			}
			t.time = p.time + 1;//时间+1
			q.push(t);

		}
	}
	return -1;
}
int main()
{
	int n; cin >> n;
	while (n--)
	{
		memset(visit, 0, sizeof(visit));//每回合一定要用memset初始化二维数组
		cin >> a >> b;
		for (int i = 0; i < a; i++)
		{
			for (int j = 0; j < b; j++)
			{
				cin >> map[i][j];
				if (map[i][j] == 2)//起点
				{
					x1 = i;
					y11 = j;
				}
				else if (map[i][j] == 3)//终点
				{
					x2 = i;
					y2 = j;
				}
			}
		}
		cout << bfs() << endl;;
	}
}

  游戏开发 最新文章
6、英飞凌-AURIX-TC3XX: PWM实验之使用 GT
泛型自动装箱
CubeMax添加Rtthread操作系统 组件STM32F10
python多线程编程:如何优雅地关闭线程
数据类型隐式转换导致的阻塞
WebAPi实现多文件上传,并附带参数
from origin ‘null‘ has been blocked by
UE4 蓝图调用C++函数(附带项目工程)
Unity学习笔记(一)结构体的简单理解与应用
【Memory As a Programming Concept in C a
上一篇文章      下一篇文章      查看所有文章
加:2021-09-12 13:27:58  更:2021-09-12 13:30:05 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年5日历 -2024/5/17 12:12:40-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码