当前位置: 首页 > news >正文

[BFS广搜]迷阵

描述

小Z每年都会为程设课出一道大作业,荼毒学弟学妹,可谓罪大恶极不可饶恕。

终于有一天,神明也看不下去了,他唤醒上古四大神兽,决定围困小Z,威慑一番。

于是,在小Z下一次醒来时,他便发现自己已然身处不知名的所在,抬眼所见,只有滚滚迷雾席卷而来,雾霭深处还隐隐约约闪着雷光。

低头一看,地上有一红漆木盒,上书四个大字“求生之道”,打开一看,竟是一台电脑。

电脑上空荡荡的,只有三个文件,一个是 Visual Studio 的安装包,一个是 README.txt,还有一个是 map.png。

小Z想都没想就开始安装 VS,在漫长的等待中,他打开了 README.txt:

“汝罪大恶极,故略施薄惩。此乃四象迷阵,有神兽镇守,踏错一步,险象环生。如欲得生,须观 map.png,寻得最短出路。”
 



迷阵是 m 行 n 列的格子矩阵,行、列从 1 开始数。小Z出生在左上角,也就是第 1 行,第 1 列的格子,迷阵的出口在第 m 行,第 n 列。

迷阵中有三种格子:

1. 空格子,以英文句点'.'记。出生点和出口都是空格子。
2. 墙,以井号'#'记。小Z无法移动到墙上。
3. 陷阱,以星号'*'记。小Z移动到陷阱的瞬间会受到来自上古神兽的 1 点伤害(生命 - 1),但是离开陷阱的瞬间不会再受到伤害。

小Z的生命有 H 点,当生命到 0 的瞬间他就会被传送回出生点。

小Z的每次行动是向上下左右的四个方向之一移动一格。不能移动出界,不能移动到墙上,但是可以移动到陷阱上。

小Z需要在短短3个小时内写出程序,算出自己最少要走多少步才能走到出口。

但凡迷阵,必有生门。题目保证必定存在一条路径使得小Z能够走到出口。

输入

第一行是一个整数 T,表示输入包含 T 组数据,分别是不同的平行时空下小Z所处的迷阵。

对于每组数据,第一行包括三个整数:m(2 <= m <= 255)、n(2 <= n <= 255)、H(1 <= H <= 5)。

接下来 m 行,每行是一个由符号组成的长度为 n 的字符串,第 i 行的第 j 个字符表示矩阵中第 i 行第 j 列的格子的类型。

题目保证出生点和出口(左上角和右下角)都是空格子。

输出

对于每组数据,你需要输出一行一个正整数,表示小Z在这个迷阵中最少要走多少步才能走到出口。

题目保证小Z一定能走到出口。

样例输入

2
2 2 3
.*
#.
5 5 3
.....
****.
.....
.****
.....

样例输出

2
8
解题分析

很经典的广搜题加上了一定的限制条件,所以我们也相应地给visited数组多加上一点维度来判断是否经过。由于多次吃亏,我们还是决定在放入数组的那个时候直接标记visited,避免扩展无用节点导致memory limited exceed!!然后,如果生命值归0了,说明这个路径是不行的,我们也不用继续放进队列扩展了,然后如果说现在的步数已经比答案要更大了,也没有必要放进去,这种减枝是很有效的。

代码实现
#include <iostream>
#include <algorithm>
#include <cmath>
#include <cstring>
#include <queue>
using namespace std;
int m,n,H;
char maze[260][260];
int dx[]={-1,1,0,0};
int dy[]={0,0,-1,1};
bool visited[260][260][6];struct Node{int x,y,H;int step;Node(int a=0,int b=0,int c=0,int d=0) : x(a),y(b),H(c),step(d) {}
};int main(){int T;scanf("%d",&T);while(T--){memset(visited,0,sizeof(visited));scanf("%d%d%d",&m,&n,&H);for(int i=1;i<=m;i++)for(int j=1;j<=n;j++){scanf(" %c",&maze[i][j]);}int ans=1e9;queue<Node> q;q.push({1,1,H,0});while(!q.empty()){Node tmp=q.front();q.pop();if(tmp.x==m && tmp.y==n){ans=min(ans,tmp.step);break;}for(int i=0;i<4;i++){int x1=tmp.x+dx[i];int y1=tmp.y+dy[i];if(x1>=1 && x1<=m && y1>=1 && y1<=n  && maze[x1][y1]!='#'){int tmph=tmp.H;if(maze[x1][y1]=='*') tmph-=1;if(tmph && visited[x1][y1][tmph]==0 && tmp.step+1<ans){q.push({x1,y1,tmph,tmp.step+1});visited[x1][y1][tmph]=1;}} }}printf("%d\n",ans);}return 0;
}

相关文章:

  • Android 一个改善的okHttp封装库
  • 第十一章:接口
  • Linux C编译器从零开发三
  • 02-ES6新语法
  • shell 三剑客-grep
  • SpringSecurity-入门代码
  • 【Linux】如何创建yum 组(yum groups)
  • 计算机类期刊含金量横纵向对比(一)
  • 计算机网络 —— 运输层(UDP和TCP)
  • 面试专区|【32道HDFS高频题整理(附答案背诵版)】
  • 2024 年 Python 基于 Kimi 智能助手 Moonshot Ai 模型搭建微信机器人(更新中)
  • 003.Linux SSH协议工具
  • 工具清单 - CI CD
  • GaussDB技术解读——GaussDB架构介绍(五)
  • 如何快速翻译pdf英文论文(5分钟就可以翻译一篇几十页的英文论文)
  • 【Amaple教程】5. 插件
  • 【JavaScript】通过闭包创建具有私有属性的实例对象
  • 0基础学习移动端适配
  • css属性的继承、初识值、计算值、当前值、应用值
  • ES6 学习笔记(一)let,const和解构赋值
  • js写一个简单的选项卡
  • Synchronized 关键字使用、底层原理、JDK1.6 之后的底层优化以及 和ReenTrantLock 的对比...
  • ⭐ Unity + OpenCV 实现实时图像识别与叠加效果
  • vue2.0一起在懵逼的海洋里越陷越深(四)
  • 阿里中间件开源组件:Sentinel 0.2.0正式发布
  • 分布式任务队列Celery
  • 海量大数据大屏分析展示一步到位:DataWorks数据服务+MaxCompute Lightning对接DataV最佳实践...
  • 实现菜单下拉伸展折叠效果demo
  • 物联网链路协议
  • 移动端唤起键盘时取消position:fixed定位
  • 智能合约Solidity教程-事件和日志(一)
  • mysql面试题分组并合并列
  • 阿里云ACE认证学习知识点梳理
  • ​2021半年盘点,不想你错过的重磅新书
  • ​渐进式Web应用PWA的未来
  • ​力扣解法汇总946-验证栈序列
  • ​浅谈 Linux 中的 core dump 分析方法
  • ‌分布式计算技术与复杂算法优化:‌现代数据处理的基石
  • # 20155222 2016-2017-2 《Java程序设计》第5周学习总结
  • (1)Hilt的基本概念和使用
  • (20)目标检测算法之YOLOv5计算预选框、详解anchor计算
  • (PHP)设置修改 Apache 文件根目录 (Document Root)(转帖)
  • (Redis使用系列) SpirngBoot中关于Redis的值的各种方式的存储与取出 三
  • (二十五)admin-boot项目之集成消息队列Rabbitmq
  • (附源码)spring boot儿童教育管理系统 毕业设计 281442
  • (更新)A股上市公司华证ESG评级得分稳健性校验ESG得分年均值中位数(2009-2023年.12)
  • (详细版)Vary: Scaling up the Vision Vocabulary for Large Vision-Language Models
  • (一)C语言之入门:使用Visual Studio Community 2022运行hello world
  • (原創) 如何刪除Windows Live Writer留在本機的文章? (Web) (Windows Live Writer)
  • (转)nsfocus-绿盟科技笔试题目
  • (轉貼) 寄發紅帖基本原則(教育部禮儀司頒布) (雜項)
  • *** 2003
  • .bashrc在哪里,alias妙用
  • .net 4.0发布后不能正常显示图片问题
  • .NET Framework杂记