2021寒假每日一题《献给阿尔吉侬的花束》

献给阿尔吉侬的花束

题目来源:《信息学奥赛一本通》
时间限制: 1000 m s 1000ms 1000ms 内存限制: 64 m b 64mb 64mb

题目描述

阿尔吉侬是一只聪明又慵懒的小白鼠,它最擅长的就是走各种各样的迷宫。
今天它要挑战一个非常大的迷宫,研究员们为了鼓励阿尔吉侬尽快到达终点,就在终点放了一块阿尔吉侬最喜欢的奶酪。
现在研究员们想知道,如果阿尔吉侬足够聪明,它最少需要多少时间就能吃到奶酪。
迷宫用一个 R ∗ C R*C RC 的字符矩阵来表示。
字符 S S S 表示阿尔吉侬所在的位置,字符 E E E 表示奶酪所在的位置,字符 # \# # 表示墙壁,字符 . . . 表示可以通行。
阿尔吉侬在 1 1 1 个单位时间内可以从当前的位置走到它上下左右四个方向上的任意一个位置,但不能走出地图边界。

输入格式

第一行是一个正整数 T T T ,表示一共有 T T T 组数据。
每一组数据的第一行包含了两个用空格分开的正整数 R R R C C C ,表示地图是一个 R ∗ C R*C RC 的矩阵。
接下来的 R R R 行描述了地图的具体内容,每一行包含了 C C C 个字符。字符含义如题目描述中所述。保证有且仅有一个 S S S E E E

输出格式

对于每一组数据,输出阿尔吉侬吃到奶酪的最少单位时间。
若阿尔吉侬无法吃到奶酪,则输出“oop!”(只输出引号里面的内容,不输出引号)。
每组数据的输出结果占一行。

数据范围

1 < T ≤ 10 1 < T ≤ 10 1<T10 ,
2 ≤ R , C ≤ 200 2 ≤ R,C ≤ 200 2R,C200

样例输入

3
3 4
.S..
###.
..E.
3 4
.S..
.E..
....
3 4
.S..
####
..E.

样例输出

5
1
oop!

解题思路:BFS

拿到给定的 R ∗ C R*C RC 的数组后,先遍历拿到 S S S E E E 的坐标,用pair类对象来保存。

BFS思路: 将当前坐标的上下左右四个格子遍历一边,如果能走,就将能走的格子的坐标放入队列,循环内依次出列,再继续遍历出列的格子的上下左右,如此循环,知道没有格子可以走,即队列为空,就结束。

先将起始坐标入队,开一个 d i s t dist dist 数组用于保存距离,并将起始坐标的距离写为0。
进入循环,出队一个 pair t ,遍历此坐标的上下左右四个格子,如果能走,则将其坐标入队,并直接赋值距离 dist[x][y] = dist[t.x][t.y] + 1 ,所有走过的格子将其标记为不能走。
循环直到走到了终点坐标即返回终点坐标距离 dist[e.x][e.y] ,如果队列为空的时候还未走到终点,循环结束,返回 oop!

类似题目: 2021寒假每日一题《红与黑》

解题代码-Java

import java.util.Queue;
import java.util.Scanner;
import java.util.LinkedList;

class pair {
    int x, y;

    public pair(int x, int y) {
        this.x = x;
        this.y = y;
    }
}

public class Main {
    static int r, c;
    static char[][] maze;
    static int[][] dist;
    static int[] dx = new int[]{0, 1, 0, -1};
    static int[] dy = new int[]{-1, 0, 1, 0};

    static String bfs(pair s, pair e) {
        Queue<pair> q = new LinkedList<>();
        q.offer(s);
        dist[s.x][s.y] = 0;
        while (!q.isEmpty()) {
            pair t = q.poll();

            for (int i = 0; i < 4; i++) {
                int x = t.x + dx[i], y = t.y + dy[i];
                if (x >= 0 && x < r && y >= 0 && y < c && maze[x][y] != '#') {
                    maze[x][y] = '#';
                    dist[x][y] = dist[t.x][t.y] + 1;
                    if (x == e.x && y == e.y) {
                        return "" + dist[x][y];
                    }
                    q.offer(new pair(x, y));
                }
            }
        }
        return "oop!";
    }

    public static void main(String[] args) {
        Scanner input = new Scanner(System.in);
        int t = input.nextInt();
        while (t-- > 0) {
            r = input.nextInt();
            c = input.nextInt();
            maze = new char[r][c];
            dist = new int[r][c];
            pair s = null, e = null;
            for (int i = 0; i < r; i++) {
                maze[i] = input.next().toCharArray();
                for (int j = 0; j < c; j++) {
                    if (maze[i][j] == 'S') {
                        s = new pair(i, j);
                    }
                    if (maze[i][j] == 'E') {
                        e = new pair(i, j);
                    }
                }
            }
            System.out.println(bfs(s, e));
        }
        input.close();
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
以下是NBA历史前50大巨星的排名: 1. 迈克尔·乔丹(Michael Jordan) 2. 拉里·伯德(Larry Bird) 3. 魔术师约翰逊(Magic Johnson) 4. 比尔·拉塞尔(Bill Russell) 5. 奥斯卡·罗伯特森(Oscar Robertson) 6. 威尔特·张伯伦(Wilt Chamberlain) 7. 科比·布莱恩特(Kobe Bryant) 8. 蒂姆·邓肯(Tim Duncan) 9. 杰里·韦斯特(Jerry West) 10. 卡里姆·阿卜杜勒-贾巴尔(Kareem Abdul-Jabbar) 11. 朱利叶斯·欧文(Julius Erving) 12. 伦纳德·弗洛伊德(Lenoard Fournette) 13. 卡尔·马龙(Karl Malone) 14. 莫西·马龙(Moses Malone) 15. 查尔斯·巴克利(Charles Barkley) 16. 艾伦·艾弗森(Allen Iverson) 17. 费城76人乔治·麦肯(George Mikan) 18. 艾尔金·贝勒(Elgin Baylor) 19. 斯蒂夫·纳什(Steve Nash) 20. 詹姆斯·哈登(James Harden) 21. 凯文·加内特(Kevin Garnett) 22. 阿尔吉·贝勒(Archie Bel) 23. 詹姆斯·沃西(James Worthy) 24. 约翰·哈维切克(John Havlicek) 25. 科林·考珀(Kawhi Leonard) 26. 伯纳德·金(Bernard King) 27. 艾迪·琼斯(Eddie Jones) 28. 吉姆·邦德(Jim Boud) 29. 鲍勃·卡尔(Bob Cousy) 30. 波比·琼斯(Bobby Jones) 31. 格兰特·希尔(Grant Hill) 32. 贾马尔·威尔士(Jamaal Wilkes) 33. 瑞克·巴里(Rick Barry) 34. 克莱德·德雷克斯勒(Clyde Drexler) 35. 约翰·斯托克顿(John Stockton) 36. 埃尔文·海耶斯(Elvin Hayes) 37. 格奥尔格·加瓦尼(George Gervin) 38. 丹尼斯·罗德曼(Dennis Rodman) 39. 阿尔·杰弗森(Al Jefferson) 40. 肖恩·肯普(Shawn Kemp) 41. 杰森·基德(Jason Kidd) 42. 克里斯·波什(Chris Bosh) 43. 安东尼奥·麦克迪斯(Antonio McDyess) 44. 贾森·威廉姆斯(Jayson Williams) 45. 恩尼斯特·威廉姆斯(Eniest Wil) 46. 维诺·贾努比利(Manu Ginobili) 47. 格伦·莱斯(Glen Rice) 48. 丹尼尔·吉布森(Daniel Gibson) 49. 布莱恩·斯卡拉布林(Brian Scalabrine) 50. 萨姆·卡塞尔(Sam Cassell)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

胡人天

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值