1.迷宫寻路

题目描述

假设一个探险家被困在了地底的迷宫之中,要从当前位置开始找到一条通往迷宫出口的路径。迷宫可以用一个二维矩阵组成,有的部分是墙,有的部分是路。迷宫之中有的路上还有门,每扇门都在迷宫的某个地方有与之匹配的钥匙,只有先拿到钥匙才能打开门。请设计一个算法,帮助探险家找到脱困的最短路径。如前所述,迷宫是通过一个二维矩阵表示的,每个元素的值的含义如下 0-墙,1-路,2-探险家的起始位置,3-迷宫的出口,大写字母-门,小写字母-对应大写字母所代表的门的钥匙

输入描述:

迷宫的地图,用二维矩阵表示。第一行是表示矩阵的行数和列数M和N
后面的M行是矩阵的数据,每一行对应与矩阵的一行(中间没有空格)。M和N都不超过100, 门不超过10扇。

输出描述:

路径的长度,是一个整数
示例1

输入

5 5
02111
01a0A
01003
01001
01111

输出

7

思路:用BFS, 创建类,成员中包含坐标,携带的钥匙,在这个坐标是第几步 三个信息。 其中钥匙的字母不超过26,INT的位数超过26,   所以可以用一位int值的位运算保存持有的钥匙, 用三维数组,标识 此状态下(钥匙持有状态)是否走过此坐标。需要注意的地方:  Scanner 的 nextLine() 要提前多用一次吃点回车,或者用next()一个一个录入          不要搞混 行于列 的关系  = =  
static int min=999999;static char[][] map=new char[110][110];static int next[][]={{1,0},{-1,0},{0,1},{0,-1}};static int m,n;static int [][][] visit = new int[110][110][1500];public static void main(String[] args) {Scanner sc = new Scanner(System.in);m=sc.nextInt();n=sc.nextInt();sc.nextLine();for(int i=0;i<m;i++) {map[i] = sc.nextLine().toCharArray();}for(int i=0;i<m;i++){for(int j=0;j<n;j++){if(map[i][j]=='2'){System.out.println(bfs(i,j));return;          }}}}static int bfs(int x,int y){/*** 首先拿到入口,压入queue* 开始判空que循环,* 用next数组,做循环判断四个方向,越界continue* 是出口,返回node.step +1* 是小写,用(1<<char-'a')| node.k ,存储钥匙* 是大写,判断有没有钥匙,没钥匙continue* 判断可走,在三维数组中写为1*      并将新构建Node(携带最新的key,并step+1)压入queue*/LinkedList<Node> queue= new LinkedList<>();queue.offer(new Node(x,y,0,0));while(queue.size()>0){Node t= queue.poll();//System.out.println(" "+t.x+","+t.y+" ->"+t.k+" ===="+t.step);for(int k=0;k<4;k++){int mx = t.x+next[k][0];int my = t.y+next[k][1];int key=t.k;if(mx<0||mx>=n||my<0||my>=m||map[mx][my]=='0')continue;if(map[mx][my]=='3')return t.step+1;if(map[mx][my]>='A'&&map[mx][my]<='Z'){int o=map[mx][my]-'A';if((key&(1<<o))==0)continue;}if(map[mx][my]>='a'&&map[mx][my]<='z'){key=(1<<map[mx][my]-'a')|key;}if(visit[mx][my][key]==0) {visit[mx][my][key] = 1;queue.offer(new Node(mx,my,key,t.step+1));}}}return -1;}public static class Node {int x, y, k, step;public Node(int x, int y, int k, int step) {this.x = x;this.y = y;this.k = k;this.step = step;}}

2.推箱子游戏

有一个推箱子的游戏, 一开始的情况如下图:
上图中, '.' 表示可到达的位置, '#' 表示不可到达的位置,其中 S 表示你起始的位置, 0表示初始箱子的位置, E表示预期箱子的位置,你可以走到箱子的上下左右任意一侧, 将箱子向另一侧推动。如下图将箱子向右推动一格;

..S0.. -> ...S0.

注意不能将箱子推动到'#'上, 也不能将箱子推出边界;

现在, 给你游戏的初始样子, 你需要输出最少几步能够完成游戏, 如果不能完成, 则输出-1。

输入描述:
第一行为2个数字,n, m, 表示游戏盘面大小有n 行m 列(5< n, m < 50);后面为n行字符串,每行字符串有m字符, 表示游戏盘面;
输出描述:
一个数字,表示最少几步能完成游戏,如果不能,输出-1;
输入例子1:
3 6
.S#..E
.#.0..
......
输出例子1:
11

思路:BFS,与上题不同的是,上题需要记录的“状态”是钥匙的携带情况,此题的“状态”是“箱子的位置”,(即状态相同的情况下,      走过的位置不饿能再走)      每次判断移动后是否到了箱子的位置,如果是,则箱子也被推动,保存刷新的状态。      如果不是,则进行普通的保存      如果状态箱子的位置等于出口,则返回结果
import java.util.*;public class Main {static char[][] map=new char[110][110];static int next[][]={{1,0},{-1,0},{0,1},{0,-1}};static int m,n;static int [][][][] visit = new int[60][60][60][60];public static void main(String[] args) {Scanner sc = new Scanner(System.in);n=sc.nextInt();m=sc.nextInt();sc.nextLine();for(int i=0;i<n;i++) {map[i] = sc.nextLine().toCharArray();}int r1=0,r2=0,b1=0,b2=0;for(int i=0;i<n;i++){for(int j=0;j<m;j++){if(map[i][j]=='S') {r1 = i;r2 = j;}if(map[i][j]=='0'){b1=i;b2=j;}}}System.out.println(bfs(r1,r2,b1,b2));}static int bfs(int r1,int r2,int b1,int b2){LinkedList<Node> queue=new LinkedList<>();queue.offer(new Node(r1,r2,b1,b2));visit[r1][r2][b1][b2]=1;while(queue.size()>0){Node t= queue.poll();if(map[t.bx][t.by]=='E'){return visit[t.x][t.y][t.bx][t.by]-1;}for(int k=0;k<4;k++){int mx=t.x+next[k][0];int my=t.y+next[k][1];//System.out.println(mx+" ---- "+my);if(mx<0||mx>=n||my<0||my>=m||map[mx][my]=='#')continue;if(mx==t.bx&&my==t.by){int mbx=t.bx+next[k][0];int mby=t.by+next[k][1];if(mbx>=n||mbx<0||mby<0||mby>=m||map[mbx][mby]=='#'||visit[mx][my][mbx][mby]!=0)continue;visit[mx][my][mbx][mby]= visit[t.x][t.y][t.bx][t.by]+1;queue.offer(new Node(mx,my,mbx,mby));}else{if(visit[mx][my][t.bx][t.by]!=0)continue;visit[mx][my][t.bx][t.by] = visit[t.x][t.y][t.bx][t.by]+1;queue.offer(new Node(mx,my,t.bx,t.by));}}}return -1;}public static class Node {int x, y, bx, by;public Node(int x, int y, int bx, int by) {this.x = x;this.y = y;this.bx = bx;this.by = by;}}
}

转载于:https://www.cnblogs.com/xfdmyghdx/p/10564401.html

题目:两道迷宫类型题相关推荐

  1. 3CTF的两道流量分析题

    文章目录 第一道忘了叫啥了 第二道好像是叫黑客攻击啥的 方法一:使用mimikatz 方法二:利用Windows Password Recovery软件 第一道忘了叫啥了 题目链接:https://u ...

  2. 两道小学生的题----1000: 梦里的难题、1002: 拳皇

    黑色的飞鸟掠过天空,我站在城中,看时间燃成灰烬,哗哗作响...... 题目描述 生化危机血腥暴力的场面对小星星的冲击很大,晚上频繁地做起了梦,梦里他担负起拯救世人消灭僵尸的重任,眼看就能拿到消除 T ...

  3. 华为外包l两道面试算法题。

    今日下午刚结束面试.一共两技术人员面的,一人出了一道算法题,记录下,并为以后做些准备,由于远程面试,所以没有代码测试,不知道行不行的通,且行且看吧. 1.输入为String 字母卡片(可以重复)和一个 ...

  4. 【数学分析】存在覆盖有理数但不能覆盖实数的区间之并——两道相关证明题

    文章目录 题目 (1)直接放缩 (2) 法一:容易理解的放缩做法 法二:更为构造的做法 总结 题目 看到这么一个视频,发现算法竞赛味挺浓,而且能看懂,就水了这么一篇blog~ 2022年某校数学分析① ...

  5. Java多道程序坐标图_两道java基础题,每天赶任务,多忘了怎么写这种代码。

    题目: 输入一整数,找出大于该整数的最小完美数,找到返回该数,找不到返回0. 完美数:一个数如果恰好除与各位书的和余22,这个数就成为"完美数". 审题 再看一遍,整数应该包括负数 ...

  6. 在两道多线程基础题“顺序打印”中对比一下Java中的wait()和join()

    目录 一.基础 二.进阶 一.基础 有三个线程,线程名称分别为:a,b,c,每个线程打印自己的名称. 需要让他们同时启动,并按 c,b,a的顺序打印. 这道题要求打印 cba,且只打印一次.如何保证线 ...

  7. 俯视两道中学平面几何题

    我现在看到几何类的中学试题,优先考虑如果用"解析方法"无视几何背景.采用高等一些的数学方法暴力解题的可能性. 比如下面这个问题,如果从带约束的非线性优化的角度看,就是求以四边形的面 ...

  8. 腾讯实习生面试2016两道面试题目?(知乎)

    腾讯实习生面试2016两道面试题目?修改 谢谢大神们高质量的回答,满满干货,excited ------------------------------------------------------ ...

  9. 数学智力题 武士数独题目_这5道数学智力题,“虐哭”很多家长,难倒众多大学生...

    作为家长来说,最闹心的事情莫过于是辅导孩子的功课了.网络一直流传这样的一句话:"不写作业母慈子孝,一写作业鸡飞狗跳".一半的原因是由于孩子的不配合,还有一部分是因为现在的数学题目确 ...

最新文章

  1. Doxygen使用介绍
  2. stl_vector.h
  3. 用python读取股票价格_使用Python写一个量化股票提醒系统
  4. python练习题:使用循环和函数实现一个摇骰子小游戏
  5. windows简易使用composer 安装国内镜像
  6. 为vim编辑器增加行号功能
  7. 前端学习(2609):vuex的使用步骤
  8. 2797:最短前缀 Trie
  9. 南航计算机学院岳涛,自动化学院 - 南京航空航天大学
  10. 利用navicat for mysql实现mysql数据库表结构复制
  11. js+springMVC 提交数组数据到后台
  12. 椭圆极点极线性质_【气贯长虹】教你认清极点极线的真面目虽粗浅,但绝对受益!!!...
  13. 怎么把git代码导入到本地仓库_git在本地仓库添加了一个tag,如何把这个tag同步到远程仓库?...
  14. 【音乐欣赏】《Sunflower》 - Post Malone / Swae Lee
  15. 【优化预测】基于matlab差分进化改进灰狼算法优化SVR预测【含Matlab源码 1283期】
  16. 柬埔寨攻略―签证、机票
  17. Android 广播(Broadcast)
  18. 小黑公司团建吃烤肉肉啦,mac m1死活安装不上hbase,用拯救者一下就安上啦的leetcode之旅:865. 具有所有最深节点的最小子树
  19. 用jacob为word表格设置边框线
  20. android自定义插值器_自定义缓动插值器,可在Android中实现有意义的动作

热门文章

  1. 不定期备考小tips[数模][0] #20210529
  2. Unity中UI组件
  3. 万物Linux皆可刷安卓,万物皆可Win,开发者成功在安卓手机刷入Win10系统
  4. 名片识别,史上最简单的集成攻略来啦!附有SDK包
  5. 风口之上,车联网系统到底会不会是“另一个”智能手机系统?
  6. shell命令 ffmpeg 批量提取视频的音频文件
  7. html背景斜线,巧妙的实现 CSS 斜线(炫酷的小效果)
  8. 常见嵌入式WEB服务器
  9. 惠普omen测试软件,性能测试:高品质体验主流游戏
  10. Unity的摄像机拉近拉远和旋转脚本实现