【Java校招面试】实战算法(三)——宝箱怪(百度)


前言

“实战算法”是本专栏的第三个部分,本篇博文是第三篇博文,主要讲解百度笔试题——宝箱怪——的解法,如有需要,可:

  1. 点击这里,返回本专栏的索引文章
  2. 点击这里,返回上一篇《【Java校招面试】实战算法(二)——2的N次方(迅雷)》
  3. 点击这里,前往下一篇《【Java校招面试】实战算法(四)——被3整除(网易)》

一、题目描述

宝箱怪是游戏中常见的一种怪物,它们伪装成普通的宝箱,并在被玩家打开时攻击玩家。假设你操控的游戏角色身处一个放着N个宝箱的房间,每个宝箱或者是普通的宝箱,或者是宝箱怪。每个宝箱上都贴着一张字条,字条上写着以下两种信息中的一种:
①第x个宝箱是普通宝箱;
②第x个宝箱是宝箱怪。

其中普通宝箱上的信息一定是真的,而宝箱怪上的信息可能是假的,那么根据这些信息,有多少个宝箱一定是普通宝箱,又有多少个宝箱一定是宝箱怪?

  1. 输入描述
    第一行包含一个整数N1≤N≤10^5.
    接下来N行,第i行包含两个整数tx1≤t≤2, 1≤x≤N. 若t=1,则第i个宝箱上的信息为:第x个宝箱是普通宝箱;若t=2,则第i个宝箱上的信息为:第x个宝箱是宝箱怪。

  2. 输出描述
    输出两个以空格隔开的整数,第一个整数表示可以确定为普通宝箱的宝箱数量,第二个整数表示可以确定为宝箱怪的宝箱数量。

  3. 样例输入
    3
    1 2
    2 1
    1 3

  4. 样例输出
    0 1

  5. Hint
    每个宝箱都可能是宝箱怪,其中第一个宝箱一定是宝箱怪。


二、解题思路

这个题主要在于如何判定一个宝箱是宝箱怪还是普通宝箱的问题。因为只有宝箱怪可能说假话,因此只有当一个宝箱说另一个确定是宝箱怪的宝箱是普通宝箱时,才能证实前者是一个宝箱怪。

因为题目中说第一个宝箱一定是个宝箱怪,因此,通过多次迭代,第一次就找说第一个宝箱是普通宝箱的宝箱,他们一定是宝箱怪;第二次再找说在第一轮中排查出的宝箱怪是普通宝箱的宝箱……依次类推,直到排查出所有的宝箱怪。

而普通宝箱是没有办法确定的,因此一定是0.


三、代码实现

  1. 计算方法
    public static int[] Judge(List<Integer[]> numbers) {
        HashSet<Integer> mimics = new HashSet<>();
        mimics.add(1);

        boolean remainsMonster = true;
        while (remainsMonster) {
            for (int i = 1; i < numbers.size(); i++) {
                Integer[] number = numbers.get(i);
                if (number[0] == 1 && mimics.contains(number[1])) {
                    mimics.add(i);
                }
            }
            remainsMonster = false;

            for (int i = 1; i < numbers.size(); i++) {
                Integer[] number = numbers.get(i);
                if (number[0] == 1 && mimics.contains(number[1]) && !mimics.contains(i)) {
                    remainsMonster = true;
                    break;
                }
            }
        }
        return new int[]{0, mimics.size()};
    }

说明: 因为需要判断需不需要进行下一次迭代,最后的for循环是必须的。

  1. 主方法(包括输入输出)
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        int count = scanner.nextInt();
        List<Integer[]> numbers = new ArrayList<>();
        numbers.add(null);
        scanner.nextLine();
        int counter = 0;
        while (counter < count) {
            String line = scanner.nextLine().trim();
            String[] valueString = line.split(" ");
            Integer[] valueArray = new Integer[2];
            valueArray[0] = Integer.parseInt(valueString[0]);
            valueArray[1] = Integer.parseInt(valueString[1]);
            numbers.add(valueArray);
            counter++;
        }

        int[] result = Judge(numbers);
        System.out.println(result[0] + " " + result[1]);
    }

后记

这个题目思路上想通了之后,代码方面中规中矩,没有什么难度

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

IMplementist

你的鼓励,是我继续写文章的动力

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

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

打赏作者

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

抵扣说明:

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

余额充值