蓝桥杯2022年第十三届决赛真题-小球称重

目录

题目描述

输入格式

输出格式

样例输入

样例输出

提示

原题链接

代码思路


题目描述

小蓝有 N 个小球,编号 1 至 N。其中 N − 1 是正品,重量相同;有 1 个是次品,重量比正品轻。 

为了找出次品,小蓝已经用天平进行了 M 次称重,并且记录下来每次两边放的小球编号,和称重结果。 

请你根据记录,判断还剩下几个小球有次品的嫌疑。 

输入格式

第一行包含 2 个整数 N 和 M。

以下包含 M 次称重记录,每个记录占 4 行。

第一行是一个整数 K,表示天平两边各放了 K 个小球。

第二行包含 K 个整数,代表放在天平左边的小球编号。

第三行包含 K 个整数,代表放在天平右边的小球编号。

第四行是一个字符,为 ‘>’, ‘<’, ‘=’ 之一。‘>’ 代表左边比右边重,‘<’ 代表左边比右边轻,‘=’ 代表两边重量相等。

在一次称重中保证每个小球最多出现 1 次。

输出格式

输出一个整数,代表答案。

样例输入

10 2
3
1 2 3
4 5 6
<
2
3 7
8 9
=

样例输出

2

提示

{1, 2, 3} < {4, 5, 6} 能判断出次品在 {1, 2, 3} 之中。

{3, 7} = {8, 9} 能判断出 3 不可能是次品。

所以只剩下 {1, 2} 可能是次品。

对于 40% 的数据,1 ≤ N ≤ 106 ;

对于 100% 的数据,1 ≤ N ≤ 109 , 1 ≤ M ≤ 105 , 参与 M 次称重的小球总数 ≤ 106 .

原题链接

题目 2720: 蓝桥杯2022年第十三届决赛真题-小球称重https://www.dotcpp.com/oj/problem2720.html

代码思路

代码中调用HashSet集合的函数 介绍

isEmpty():用于判断HashSet是否为空.如果HashSet为空,则返回True,否则返回False.

contains():用于判断HashSet是否包含某个元素.如果包含指定的元素,则返回true,否则返回false.

import java.util.*;
 
public class Main {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        int n = scanner.nextInt();
        int m = scanner.nextInt();
        // HashSet可以帮助我们去重,且在查询和删除时的效率高,符合我们的需求,所以使用
        // s1存的是有嫌疑的小球
        // s2存的是没有嫌疑的小球
        Set<Integer> s1 = new HashSet<Integer>();
        Set<Integer> s2 = new HashSet<Integer>();
        // m次循环
        while (m-- > 0) {
            // s3起到一个过渡作用,将s1里没有解除嫌疑的小球存入s3,然后s3再赋值给s1,搞完一轮后然后再初始化
            Set<Integer> s3 = new HashSet<Integer>();
            int sl = scanner.nextInt();
            // ArrayList集合是在查询元素时速度很快,但在增加或删除元素时效率较低
            // 以下代码明显查询元素较多,所以最好使用ArrayList集合
            List<Integer> a = new ArrayList<Integer>();
            List<Integer> b = new ArrayList<Integer>();
            // 向a和b对象里添加小球
            for (int i = 0; i < sl; i++) {
                a.add(scanner.nextInt());
            }
            for (int i = 0; i < sl; i++) {
                b.add(scanner.nextInt());
            }
            // 记录天平的称重结果 <,>还是=
            String string = scanner.next();
            if (string.equals(">")) {
                // isEmpty()函数 是容器为空的化返回true
                if (s1.isEmpty()) {
                    // s1为空的化,将有嫌疑的小球存入
                    for (Integer p : b) {
                        // contains(元素n)函数 是有这个元素n,则返回true
                        // 如果s2里没有,s1再存入(是为了避免没有嫌疑的小球存入)
                        if (!s2.contains(p)) {
                            s1.add(p);
                        }
                    }
                } else {
                    // s1不为空,将有嫌疑的小球存入
                    for (Integer integer : b) {
                        // contains(元素n)函数 是有这个元素n返回true
                        // 如果s1里有这个小球,s3就存入(因为次品只有一个,那么缩小 嫌疑小球的范围 并存入s3中)
                        if (s1.contains(integer)) {
                            s3.add(integer);
                        } else {
                            // s1里没有的化,s2就存入(扩大没有嫌疑的小球,让判断小球有无嫌疑更加准确)
                            s2.add(integer);
                        }
                    }
                    // 将更加准确的嫌疑小球 赋值给s1
                    s1 = s3;
                }
            } else if (string.equals("<")) {
                if (s1.isEmpty()) {
                    // s1为空的化,将有嫌疑的小球存入
                    for (Integer p : a) {
                        // contains(元素n)函数 是有这个元素n,则返回true
                        // 如果s2里没有,s1再存入(是为了避免没有嫌疑的小球存入)
                        if (!s2.contains(p)) {
                            s1.add(p);
                        }
                    }
                } else {
                    // s1不为空,将有嫌疑的小球存入
                    for (Integer integer : a) {
                        // contains(元素n)函数 是有这个元素n返回true
                        // 如果s1里有这个小球,s3就存入(因为次品只有一个,那么缩小 嫌疑小球的范围 并存入s3中)
                        if (s1.contains(integer)) {
                            s3.add(integer);
                        } else {
                            // s1里没有的化,s2就存入(扩大没有嫌疑的小球,让判断小球有无嫌疑更加准确)
                            s2.add(integer);
                        }
                    }
                    // 将更加准确的嫌疑小球 赋值给s1
                    s1 = s3;
                }
            } else {
                // 天平的称重结果要是等于的化,说明两边的小球都没有嫌疑(因为次品小球只有一个,所以不可能 即有次品小球,又有两边还相等的情况)
                // 所以s1要删除没有嫌疑的小球
                // 所以s2要添加没有嫌疑的小球
                for (Integer integer : b) {
                    s1.remove(integer);
                    s2.add(integer);
                }
                for (Integer integer : a) {
                    s1.remove(integer);
                    s2.add(integer);
                }
            }
        }
 
        if (s1.isEmpty()) {
            // s1是空的话,则说明有嫌疑的小球没出现过,所以要用 (总数量-没有嫌疑的小球数量 结果是 有嫌疑的小球数量)
            System.out.println(n - s2.size());
        } else {
            // s1不为空,则直接输出有嫌疑的小球数量
            System.out.println(s1.size());
        }
    }
}

评论 11
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值