试题 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组蓝桥杯第十届国赛:大胖子走迷宫相关推荐

  1. Java B组蓝桥杯第十届国赛:最优旅行

    试题 D: 最优旅行 本题总分:10 分 [问题描述] 中国的高铁四通八达,乘坐方便,小明经常乘坐高铁在城市间旅游. 现在,小明又有了一个长假,他打算继续乘坐高铁旅游.这次,他打算到 下面的城市旅游. ...

  2. Java B组蓝桥杯第六届国赛:铺瓷砖

    这101分的题真的搞不定........ 本人能力有限,搜遍百度,没有找到完美的代码..... 倒是找到一堆文章在写多米诺骨牌版的铺地砖,但那些文章内容很杂,不知所云,无法耐心研究下去,但也许能类比到 ...

  3. 蓝桥杯国赛-大胖子走迷宫

    广度优先搜索,见注释 五个状态:上下左右停 题目提交 import java.util.ArrayDeque; import java.util.Queue; import java.util.Sca ...

  4. 蓝桥杯第十届国赛C++研究生组 试题 A: 三升序列

    试题 A: 三升序列 [问题描述] 对于一个字母矩阵,我们称矩阵中的一个三升序列是指在矩阵中找到三个 字母,它们在同一行,同一列,或者在同一 45 度的斜线上,这三个字母从左向 右看.或者从上向下看是 ...

  5. 蓝桥杯第十三届国赛PythonB组题解

    蓝桥杯第十三届国赛PythonB组题解 [写在前边] 这次的题还是比较难的,只做出来7道,交上去6道,还有一半是暴力做的

  6. 蓝桥杯国赛10-JavaB-8-大胖子走迷宫

    package b10;import java.util.HashMap; import java.util.HashSet; import java.util.Scanner; import jav ...

  7. 蓝桥杯第十届省赛java组解析(灵能传输 四星难度,后缀表达式 两星难度)

    第一题太简单懒得复制题目了 答案是:490 第二题: 试题 B: 不同子串 本题总分:5 分 [问题描述] 一个字符串的非空子串是指字符串中长度至少为 1 的连续的一段字符组成 的串.例如,字符串aa ...

  8. 蓝桥杯第六届国赛JAVA真题----切开字符串

    标题:切开字符串 Pear有一个字符串,不过他希望把它切成两段. 这是一个长度为N(<=10^5)的字符串. Pear希望选择一个位置,把字符串不重复不遗漏地切成两段,长度分别是t和N-t(这两 ...

  9. 蓝桥杯第七届国赛JAVA真题----机器人塔

    机器人塔 X星球的机器人表演拉拉队有两种服装,A和B. 他们这次表演的是搭机器人塔. 类似: 队内的组塔规则是: A 只能站在 AA 或 BB 的肩上.     B 只能站在 AB 或 BA 的肩上. ...

最新文章

  1. VS2010安装Nuget提示签名不匹配错误解决办法
  2. 哈夫曼编解码(C语言)
  3. 利用JMeter进行压力测试(1)(转)
  4. RelativeLayout重要属性
  5. 2020快手用户及营销报告
  6. JQ focus blur focusin focuseout
  7. Guava Cache 使用笔记
  8. 如何在终端启动Coda 2中隐藏的首选项?
  9. java课程设计(总结)
  10. 有感 Visual Studio 2015 RTM 简介 - 八年后回归 Dot Net,终于迎来了 Mvc 时代,盼走了 Web 窗体时代
  11. java求职英文简历范本2篇_Java英文简历范文
  12. 无人机航拍全景图拍摄教程技巧分享
  13. 指令引用的内存不能为written怎么解决
  14. 价值博客们--by 刘末鹏
  15. 鸡兔同笼python程序怎么写_鸡(土从)
  16. 玩客云 虚拟服务器设置,玩客云刷 Linux 系统后遇到的问题和设置固定 IP
  17. 伯努利分布、二项分布、概念辨析
  18. 组件分享之后端组件——用于将日志写入滚动文件的组件包lumberjack
  19. iOS Objective-C(2014-1-6 20:30、20140114,20140824,20150926、20160106、20160110、20160123)
  20. js下拉列表地址时间职位

热门文章

  1. 如何发现网站被劫持被黑DNS被污染
  2. linux修复win10启动失败,win10自动修复失败开不了机解决方法
  3. 双吉他伴奏配合的有关问题
  4. LATEX教程第四讲——那些不得不说的宏包(下)
  5. 你了解 JDK 8 Stream 数据流效率吗?千万级数据量性能如何?
  6. sap固定资产号码范围_SAP 固定资产的配置与逻辑
  7. python绘制正态分布图_用python制作正态分布图
  8. 幼麟棋牌登录流程分析
  9. 99%的人误解BLM中的“战略”与“执行”的关系及错误认为BLM/BEM就是战略解码的全部!
  10. 一招,提高 Github 成员微信群运营效率