Java B组蓝桥杯第十届国赛:大胖子走迷宫
试题 H: 大胖子走迷宫
时间限制: 1.0s 内存限制: 512.0MB 本题总分:20 分
【问题描述】
小明是个大胖子,或者说是个大大胖子,如果说正常人占用 1 × 1 的面积,
小明要占用 5 × 5 的面积。
由于小明太胖了,所以他行动起来很不方便。当玩一些游戏时,小明相比
小伙伴就吃亏很多。
小明的朋友们制定了一个计划,帮助小明减肥。计划的主要内容是带小明
玩一些游戏,让小明在游戏中运动消耗脂肪。走迷宫是计划中的重要环节。
朋友们设计了一个迷宫,迷宫可以看成是一个由 n × n 个方阵组成的方阵,
正常人每次占用方阵中 1 × 1 的区域,而小明要占用 5 × 5 的区域。小明的位置
定义为小明最正中的一个方格。迷宫四周都有障碍物。
为了方便小明,朋友们把迷宫的起点设置在了第 3 行第 3 列,终点设置在
了第 n − 2 行第 n − 2 列。
小明在时刻 0 出发,每单位时间可以向当前位置的上、下、左、右移动单
位 1 的距离,也可以停留在原地不动。小明走迷宫走得很辛苦,如果他在迷宫
里面待的时间很长,则由于消耗了很多脂肪,他会在时刻 k 变成一个胖子,只
占用 3 × 3 的区域。如果待的时间更长,他会在时刻 2k 变成一个正常人,只占
用 1 × 1 的区域。注意,当小明变瘦时迷宫的起点和终点不变。
请问,小明最少多长时间能走到迷宫的终点。注意,小明走到终点时可能
变瘦了也可能没有变瘦。
【输入格式】
输入的第一行包含两个整数 n,k。
接下来 n 行,每行一个由 n 个字符组成的字符串,字符为 + 表示为空地,
字符为 * 表示为阻碍物。
【输出格式】
输出一个整数,表示答案。
【样例输入】
9 5
+++++++++
+++++++++
+++++++++
+++++++++
+++++++++
***+*****
+++++++++
+++++++++
+++++++++
【样例输出】
16
【评测用例规模与约定】
对于 30% 的评测用例,1 ≤ n ≤ 50。
对于 60% 的评测用例,1 ≤ n ≤ 100。
对于所有评测用例,1 ≤ n ≤ 300,1 ≤ k ≤ 1000。
这样的题都是老套路题了,相对容易,基本上都是一个广度优先搜索,解决问题。
简单说一下思路:
(1)创建一个队列,将初始位置加入队列。
(2)进入while(队列是否为空)的循环,取出队头,更新时间,胖瘦,然后将其上下左右能移动的位置加入队列。
(3)细节:
a. 如何记录坐标,同步时间,胖瘦程度,还原路线(这里没用到)?
答:用一个自定义类,从队列中取出该类对象,先更新它的时间,胖瘦,然后创建新的位置节点,继承它的时间,胖瘦,并将其添加到 parent的位置。
//位置节点
class Point {
int x;//横坐标
int y;//纵坐标
int time;//时间
Point parent;//从哪个位置节点来的
int a;//肥胖程度
public Point(int x1, int y1, Point p,int t,int a1) {
this.x = x1;
this.y = y1;
this.parent = p;
this.time=t;
this.a=a1;
}
}
还原路线:相当于链表
Point p;
while (p.parent != null) {
p = p.parent;
}
b. 如何处理小明原地等待的情况?
判断他上下左右存在空位置,但是无法移动过去。因为太胖了,因此,如果存在这样的情况,就更新时间胖瘦,重新加入队列。
基本上就这些。
代码:
import java.util.Scanner;
import java.util.concurrent.ArrayBlockingQueue;public class Main {int n;//n行n列int k;//每k个小时小明瘦一圈char[][] maze;//迷宫地图boolean[][] vis;//地图访问标记ArrayBlockingQueue<Point> queue;//队列//位置节点class Point {int x;//横坐标int y;//纵坐标int time;//时间Point parent;//从哪个位置节点来的int a;//将肥胖转换成比常人的厚度,最开始为2,方便计算坐标public Point(int x1, int y1, Point p,int t,int a1) {this.x = x1;this.y = y1;this.parent = p;this.time=t;this.a=a1;}}public Main() {Scanner sn = new Scanner(System.in);n = sn.nextInt();k = sn.nextInt();maze = new char[n][n];vis = new boolean[n][n];sn.nextLine();queue = new ArrayBlockingQueue<Point>(n * n);for (int i = 0; i < n; i++) {maze[i] = sn.nextLine().trim().toCharArray();}//以上都是初始化queue.add(new Point(2, 2, null,0,2));//加入初始点vis[2][2] = true;//标记Point p=bfs();//获取到达终点的那个节点System.out.println(p.time);//输出时间
// //展示逆推路线
// while (p.parent != null) {
// System.out.println("x="+p.x+",y="+p.y+",time="+p.time+",a="+p.a);
// p = p.parent;
// }
// System.out.println("x="+p.x+",y="+p.y+",time="+p.time+",a="+p.a);}//广度优先搜索public Point bfs() {while (!queue.isEmpty()) {Point p = queue.poll();//取出队头//更新时间,胖瘦p.time++;if (p.time % k == 0 && p.a > 0)p.a--;//判断这个节点是不是已经是终点了if (p.x == n - 3 && p.y == n - 3)return p;//将四个方向可以移动的位置加入队列// 下if (check(p.x, p.y + 1,p) && !vis[p.y + 1][p.x]) {queue.add(new Point(p.x, p.y + 1, p,p.time,p.a));vis[p.y + 1][p.x] = true;}// 右if (check(p.x + 1, p.y,p) && !vis[p.y][p.x + 1]) {queue.add(new Point(p.x + 1, p.y, p,p.time,p.a));vis[p.y][p.x + 1] = true;}// 左if (check(p.x - 1, p.y,p) && !vis[p.y][p.x - 1]) {queue.add(new Point(p.x - 1, p.y, p,p.time,p.a));vis[p.y][p.x - 1] = true;}// 上if (check(p.x, p.y - 1,p) && !vis[p.y - 1][p.x]) {queue.add(new Point(p.x, p.y - 1, p,p.time,p.a));vis[p.y - 1][p.x] = true;}//如果存在空地但又无法移动,说明小明太胖了,重新加入队列,相当于等待if(exist(p.x, p.y)) {queue.add(p);}}//到不了终点,返回空return null;}// 判断p是否能移动到(x,y)public boolean check(int x, int y,Point p) {//x是否越界if (x - p.a >= 0 && x + p.a < n) {//y是否越界if (y - p.a >= 0 && y + p.a < n) {//x,y都正常,因此检查若移动后自身范围是否存在障碍物,若存在则无法移动for (int i = x - p.a; i <= x + p.a; i++) {for (int j = y - p.a; j <= y + p.a; j++) {if (maze[j][i] == '*')return false;}}//全部通过检查,可以移动return true;}}//未通过检查return false;}//检查上下左右当前还有空位public boolean exist(int x, int y) {//左if (x - 1 >= 0) {if (!vis[x - 1][y]) {return true;}}//上if (y - 1 >= 0) {if (!vis[x][y - 1]) {return true;}}//下if (y + 1 < n) {if (!vis[x][y + 1]) {return true;}}//右if (x + 1 < n) {if (!vis[x + 1][y]) {return true;}}return false;}public static void main(String[] args) {new Main();}
}
样例测试结果:(16是答案,其他的是逆推路线,以及时间,和胖瘦(a在代码注释中有解释))
16
x=6,y=6,time=16,a=0
x=5,y=6,time=15,a=0
x=4,y=6,time=15,a=0
x=3,y=6,time=13,a=0
x=3,y=5,time=12,a=0
x=3,y=4,time=11,a=0
x=3,y=3,time=10,a=0
x=3,y=2,time=11,a=0
x=2,y=2,time=5,a=1
没有找到系统能够全部测试,不确定代码有没有错误。但思路应该没啥大问题。
这一题和第六届国赛的《穿越雷区》很像,可以拿去练手
Java B组蓝桥杯第十届国赛:大胖子走迷宫相关推荐
- Java B组蓝桥杯第十届国赛:最优旅行
试题 D: 最优旅行 本题总分:10 分 [问题描述] 中国的高铁四通八达,乘坐方便,小明经常乘坐高铁在城市间旅游. 现在,小明又有了一个长假,他打算继续乘坐高铁旅游.这次,他打算到 下面的城市旅游. ...
- Java B组蓝桥杯第六届国赛:铺瓷砖
这101分的题真的搞不定........ 本人能力有限,搜遍百度,没有找到完美的代码..... 倒是找到一堆文章在写多米诺骨牌版的铺地砖,但那些文章内容很杂,不知所云,无法耐心研究下去,但也许能类比到 ...
- 蓝桥杯国赛-大胖子走迷宫
广度优先搜索,见注释 五个状态:上下左右停 题目提交 import java.util.ArrayDeque; import java.util.Queue; import java.util.Sca ...
- 蓝桥杯第十届国赛C++研究生组 试题 A: 三升序列
试题 A: 三升序列 [问题描述] 对于一个字母矩阵,我们称矩阵中的一个三升序列是指在矩阵中找到三个 字母,它们在同一行,同一列,或者在同一 45 度的斜线上,这三个字母从左向 右看.或者从上向下看是 ...
- 蓝桥杯第十三届国赛PythonB组题解
蓝桥杯第十三届国赛PythonB组题解 [写在前边] 这次的题还是比较难的,只做出来7道,交上去6道,还有一半是暴力做的
- 蓝桥杯国赛10-JavaB-8-大胖子走迷宫
package b10;import java.util.HashMap; import java.util.HashSet; import java.util.Scanner; import jav ...
- 蓝桥杯第十届省赛java组解析(灵能传输 四星难度,后缀表达式 两星难度)
第一题太简单懒得复制题目了 答案是:490 第二题: 试题 B: 不同子串 本题总分:5 分 [问题描述] 一个字符串的非空子串是指字符串中长度至少为 1 的连续的一段字符组成 的串.例如,字符串aa ...
- 蓝桥杯第六届国赛JAVA真题----切开字符串
标题:切开字符串 Pear有一个字符串,不过他希望把它切成两段. 这是一个长度为N(<=10^5)的字符串. Pear希望选择一个位置,把字符串不重复不遗漏地切成两段,长度分别是t和N-t(这两 ...
- 蓝桥杯第七届国赛JAVA真题----机器人塔
机器人塔 X星球的机器人表演拉拉队有两种服装,A和B. 他们这次表演的是搭机器人塔. 类似: 队内的组塔规则是: A 只能站在 AA 或 BB 的肩上. B 只能站在 AB 或 BA 的肩上. ...
最新文章
- VS2010安装Nuget提示签名不匹配错误解决办法
- 哈夫曼编解码(C语言)
- 利用JMeter进行压力测试(1)(转)
- RelativeLayout重要属性
- 2020快手用户及营销报告
- JQ focus blur focusin focuseout
- Guava Cache 使用笔记
- 如何在终端启动Coda 2中隐藏的首选项?
- java课程设计(总结)
- 有感 Visual Studio 2015 RTM 简介 - 八年后回归 Dot Net,终于迎来了 Mvc 时代,盼走了 Web 窗体时代
- java求职英文简历范本2篇_Java英文简历范文
- 无人机航拍全景图拍摄教程技巧分享
- 指令引用的内存不能为written怎么解决
- 价值博客们--by 刘末鹏
- 鸡兔同笼python程序怎么写_鸡(土从)
- 玩客云 虚拟服务器设置,玩客云刷 Linux 系统后遇到的问题和设置固定 IP
- 伯努利分布、二项分布、概念辨析
- 组件分享之后端组件——用于将日志写入滚动文件的组件包lumberjack
- iOS Objective-C(2014-1-6 20:30、20140114,20140824,20150926、20160106、20160110、20160123)
- js下拉列表地址时间职位
热门文章
- 如何发现网站被劫持被黑DNS被污染
- linux修复win10启动失败,win10自动修复失败开不了机解决方法
- 双吉他伴奏配合的有关问题
- LATEX教程第四讲——那些不得不说的宏包(下)
- 你了解 JDK 8 Stream 数据流效率吗?千万级数据量性能如何?
- sap固定资产号码范围_SAP 固定资产的配置与逻辑
- python绘制正态分布图_用python制作正态分布图
- 幼麟棋牌登录流程分析
- 99%的人误解BLM中的“战略”与“执行”的关系及错误认为BLM/BEM就是战略解码的全部!
- 一招,提高 Github 成员微信群运营效率