【华为OD题库-032】数字游戏-java

news2024/10/3 8:24:58

题目

小明玩一个游戏。系统发1+n张牌,每张牌上有一个整数。第一张给小明,后n张按照发牌顺序排成连续的一行。需要小明判断,后n张牌中,是否存在连续的若干张牌,其和可以整除小明手中牌上的数字.
输入描述:
输入数据有多组,每组输入数据有两行,输入到文件结尾结束。
第一行有两个整数n和m,空格隔开。m代表发给小明牌上的数字
第二行有n个数,代表后续发的n张牌上的数字,以空格隔开。
输出描述:
对每组输入,如果存在满足条件的连续若干张牌,则输出1:否则,输出0
补充说明:
1<=n<= 1000
1<=牌上的整数<= 400000输入的组数,不多于1000
用例确保输入都正确,不需要考虑非法情况
示例1
输入:
6 7
2 12 6 3 5 5
10 11
1 1 1 1 1 1 1 1 1 1
输出
0
说明:
两组输入。
第一组小明牌的数字为7,再发了6张牌。第1、2两张牌数字和为14,可以整除7,输出1。
第二组小明牌的数字为11,再发了10张牌,这10张牌数字和为10,无法整除11,输出0。

思路

以单组数据来看,对于给定数组nums,是否存在连续和能够被指定k整除?可以想到一下几种方案:

  1. 暴力破解
  2. 组合思想
  3. 前缀和

思路一:暴力破解

双层循环:
外层i表示,依次以i开始的连续数组
内存循环变量j,初始值为i。求以i开始的连续数组的和,(即nums[i]+nums[i+1]+…+nums[j]),如果存在某个和能够被k整除,那么返回1
两层遍历完了都没有找到这样的连续数组,那么返回0

思路二:组合思想

找到nums所有的子连续数组:组合思想可参考:【JAVA-排列组合】一个套路速解排列组合题。
剪枝的关键在于判断数组是否连续,path中可以存放位置,如果是连续,那么path最后一个位置应该等于当前位置-1,即:i-1=path.peekLask();
如果某个子数组的和能够被k整除,那么返回1,否则返回0

思路三:前缀和
参考leetcode原题:974. 和可被 K 整除的子数组
leetcode的题目考虑了负数,虽然本题的牌的数字不会有正数,但这里还是对正负数都考虑进来。

设P[i]为nums数组的前i项的和
对于sum(i,j)=num[i]+num[i+1]+…+num[j]=P[j]-P[i-1]。
假设nums的i~j区间的和能够被k整除。
即:sum(i,j)%k==0,即(P[j]-P[i-1])%k=0,
即:(P[j]%k - P[i-1]%k)%k=0。
考虑同为正负的情况:P[j]%k == P[i-1]%k时上式成立
如果一正一负:|P[j]%k - P[i-1]%k| = k时上式成立,假设P[j]%k为正,P[i-1]%k为负,那么去掉绝对值后表达式为:P[j]%k = k+P[i-1]%k
综合正负数的情况,表达式可以写为:(P[j]%k+k)%k == (k+P[i-1]%k)%k,即,当前缀和为s时,考虑s可能为负数的情况,那么对k求余数可以写为: (s%k+k)%k

上面的推导可能比较抽象,现在以具体数据来说明过程:
假设我们的nums为:4 5 -4 -2 -7 -3 1,k为5。以下3行分别为nums,前缀和,对k求余((s%k+k)%k)的结果:
在这里插入图片描述
依次遍历nums,找到以当前nums[j]结尾的连续数组,判断其和能够整除k的数组有多少个?
j=0时,nums[j]=4,要满足(P[j]%k - P[i-1]%k)%k=0,才能找到满足条件的连续数组,现在P[j]%k=4,是否存在P[i-1]%k=4?i必须小于等于j, 明显不存在。
j=1时,P[j]%k=4,是否存在P[i-1]%k=4,即在j前面的求余结果是否有4,第一个为4,存在(i=1)。也就是说sum(1,1)能够被5整除。
j=2时,P[j]%k=0,第三行在位置2之前是否存在0?根据上面的逻辑不存在,但是实际上此时余数都为0了,肯定是能被k整除的,可以在0的左侧假设有P[-1]=0,这样当余数为0时,就能保证一定能够找到一个相同值,从而判断为满足条件。即sum(0,2)能够被5整除
j=3,P[j]%k=3,前面找不到
j=4,P[j]%k=1,前面找不到
j=5,P[j]%k=3,找得到,当i=4时,P[3]%k=3,即sum(4,5)能够被5整除
j=6,P[j]%k=4,在其前面能够找到4,i分别为1和2时,P[0]%k=4,P[1]%k=4,即sum(1,6),sum(2,6)均能被5整除

综上:我们可以用一个变量来存放前缀和%k出现的次数,比如map。然后遍历nums,先求出当前的前缀和sum,再求余数mod=(sum%k+k)%k,然后在map中找是否存在map.get(mod)>0,如果存在,那么就找到了这样的连续数组,如果不存在,则将map.get(mod)++后继续查找。
前缀和%k的值域范围刚好为:0~k-1,所以也可以用一个数组dp来代替map,它标识的含义是,mod值等于key出现了val次。考虑到要设P[-1]=0,即mod值为0在初始状态就要出现一次,那么将dp[0]=1。

题解

给出了三种思路在本题的具体实现,前缀和确实很抽象,也不好表达,对此不理解的多看看974. 和可被 K 整除的子数组的题解

package hwod;

import java.util.*;
import java.util.stream.Collectors;

public class NumberGame {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        List<Integer> list1 = new ArrayList<>();//存放给定的牌
        List<List<Integer>> list2 = new ArrayList<>();//牌堆
        while (sc.hasNextLine()) {
            String firstLines = sc.nextLine();
            if ("".equals(firstLines)) break;
            list1.add(Arrays.stream(firstLines.split(" ")).mapToInt(Integer::parseInt).toArray()[1]);
            String secondLines = sc.nextLine();
            list2.add(Arrays.stream(secondLines.split(" ")).mapToInt(Integer::parseInt).boxed().collect(Collectors.toList()));
        }
        List<Integer> res = numberGame(list1, list2);
        for (Integer re : res) {
            System.out.println(re);
        }
    }

    private static List<Integer> numberGame(List<Integer> list1, List<List<Integer>> list2) {
        List<Integer> res = new ArrayList<>();
        for (int i = 0; i < list1.size(); i++) {
            res.add(checked3(list2.get(i), list1.get(i)));
        }
        return res;
    }

    /**
     * 暴力破解
     * @param list   牌堆
     * @param target 被除的值
     * @return 如果存在连续和能够整除target,返回1,否则返回0
     */
    private static int checked(List<Integer> list, Integer target) {
        for (int i = 0; i < list.size(); i++) {
            int sum = 0;
            for (int j = i; j < list.size(); j++) {
                sum += list.get(j);
                if (sum % target == 0) return 1;
            }
        }
        return 0;
    }

    private static int res = 0;

    /**
     * 组合思想
     * @param list
     * @param target
     * @return
     */
    private static int checked2(List<Integer> list, Integer target) {
        LinkedList<Integer> path = new LinkedList<>();
        dfs(list, 0, path, 0, target);
        return res;
    }

    private static void dfs(List<Integer> list, int start, LinkedList<Integer> path, int sum, int k) {
        if (!path.isEmpty() && sum % k == 0) {
            res = 1;
            return;
        }
        for (int i = start; i < list.size(); i++) {
            if (!path.isEmpty() && path.peekLast() != i - 1) continue;
            if (res != 0) break;
            path.addLast(i);
            dfs(list, i + 1, path, sum + list.get(i), k);
            path.removeLast();
        }
    }

    /**
     * 设P[i]为前i项的前缀和
     * sum(i,j)=num[i]+num[i+1]+...+num[j]=P[j]-p[i-1]
     * (P[j]-p[i])%k==0  ==>  (P[j]%k - p[i-1]%k)%k=0
     *
     * @param list
     * @param k
     * @return 如果存在连续和能够整除k,返回1,否则返回0
     */
    private static int checked3(List<Integer> list, Integer k) {
        int[] dp = new int[k];
        dp[0] = 1;
        int sum = 0;
        for (int i = 0; i < list.size(); i++) {
            sum += list.get(i);
            int mod = (sum % k + k) % k;
            if (dp[mod] != 0) return 1;
            dp[mod]++;
        }
        return 0;
    }
}


推荐

如果你对本系列的其他题目感兴趣,可以参考华为OD机试真题及题解(JAVA),查看当前专栏更新的所有题目。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1241010.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

NLP学习

参考&#xff1a;NLP发展之路I - 从词袋模型到Transformer - 知乎 (zhihu.com) NLP大致的发展历史。从最开始的词袋模型&#xff0c;到RNN&#xff0c;到Transformers和BERT&#xff0c;再到ChatGPT&#xff0c;NLP经历了一段不断精进的发展道路。数据驱动和不断完善的端到端的…

逻辑漏洞(业务逻辑)dami CMS

逻辑漏洞&#xff08;业务支付逻辑漏洞&#xff09;dami CMS 0x01 业务逻辑简介 业务逻辑指的是一个系统或应用程序中的实际业务规则和流程。它描述了如何处理特定的业务需求、数据和操作。业务逻辑通常是根据特定行业或组织的需求而设计的。 在软件开发中&#xff0c;业务逻…

Matplotlib颜色条的配置_Python数据分析与可视化

Matplotlib颜色条配置 基本颜色颜色条选择配色方案颜色条刻度的限制与扩展功能的设置离散型颜色条 基本颜色 Matplotlib提供了8种指定颜色的方法&#xff1a; 在[0&#xff0c;1]中的浮点值的RGB或RGBA元组&#xff08;例如 (0.1, 0.2, 0.5) 或&#xff08;0.1&#xff0c; 0.…

MacOS 成为恶意软件活动的目标

Malwarebytes 警告称&#xff0c;一个针对 Mac 操作系统 (OS) 的数据窃取程序正在通过虚假的网络浏览器更新分发给毫无戒心的目标。 Atomic Stealer&#xff0c;也称为 AMOS&#xff0c;是 Mac OS 上流行的窃取程序。 Atomic Stealer (AMOS) 恶意软件最近被发现使用“ClearFa…

使用websocket获取thingsboard设备的实时数据

背景 有一个读者前来咨询,如何实时获取设备的遥测数据。 其实tb是有提供websocket接口来获取设备数据的。而且还支持js跨域调用。下面给大家演示一下。 websocket地址 完整代码 <!DOCTYPE HTML> <html><h

2023亚太杯数学建模赛题人工精准翻译

大家好&#xff0c;亚太杯今天早上6点已经开赛啦&#xff0c;然后我在这里给大家带来赛题的精准人工翻译&#xff0c;防止大家直接用软件翻译导致某些地方乱码或者翻译不精准&#xff0c;这会导致后续做题过程出现很大偏差。 注意&#xff0c;以下翻译均免费发放word形式的哈&…

自学成为android framework高手需要准备哪些装备-千里马车载车机系统开发学习

背景 hi&#xff0c;粉丝朋友们&#xff1a; 大家好&#xff01;经常有很多学员买课同学都会问到需要准备哪些装备&#xff0c;我也回答了很多学员了&#xff0c;今天就搞一篇文章来统一说明一下&#xff0c;告诉一下大家如果你想从一个framework新手变成一个framework开发的高…

【精选】CSS入门必看知识点大合集

CSS简介 CSS概念 CSS&#xff08;Cascading Style Sheets&#xff09;层叠样式表&#xff0c;又叫级联样式表&#xff0c;简称样式表 CSS文件后缀名为.css CSS用于HTML文档中元素样式的定义 为什么需要CSS 使用css的唯一目的就是让网页具有美观一致的页面 语法 CSS 规则…

VS Code 如何搭建C/C++环境

目录 一、VS Code是什么&#xff1f; 二、VS Code下载和安装 2.1下载 2.2安装 2.3环境介绍 三、Vs Code配置C/C环境 3.1下载和配置MinGW-w64编译器套件 3.1.1下载 3.1.2配置 一、VS Code是什么&#xff1f; 跨平台&#xff0c;免费且开源的现代轻量级代码编辑器 Vis…

vivado产生报告阅读分析15-时序报告11

Report Clock Domain Crossings “ Clock Domain Crossings (CDC) ” &#xff08; 时钟域交汇 &#xff09; 报告可对设计中的时钟域交汇执行结构分析。此信息可用于识别潜在不安全的 CDC &#xff0c; 此类 CDC 可能导致亚稳态或数据一致性问题。虽然 CDC 报告与“ Clock …

C#,数值计算——插值和外推,多项式插值与外推插值(Poly_interp)的计算方法与源程序

1 文本格式 using System; namespace Legalsoft.Truffer { /// <summary> /// 多项式插值与外推插值 /// Polynomial Interpolation and /// Extrapolation interpolation routines for one dimension /// </summary> public class Poly…

Rust错误处理:Result

文章目录 简介错误匹配 Rust基础教程&#xff1a; 初步⚙ 所有权⚙ 结构体和枚举类⚙ 函数进阶⚙ 泛型和特征⚙ 并发和线程通信⚙ cargo包管理⚙ 可空类型Option Rust进阶教程&#xff1a; 用宏实现参数可变的函数⚙ 类函数宏 简介 Rust中没有提供类似try…catch之类…

排序算法--希尔排序

实现逻辑 ① 先取一个小于n的整数d1作为第一个增量&#xff0c;把文件的全部记录分成d1个组。 ② 所有距离为d1的倍数的记录放在同一个组中&#xff0c;在各组内进行直接插入排序。 ③ 取第二个增量d2小于d1重复上述的分组和排序&#xff0c;直至所取的增量dt1(dt小于dt-l小于……

2023 年 亚太赛 APMCM (B题)国际大学生数学建模挑战赛 |数学建模完整代码+建模过程全解全析

当大家面临着复杂的数学建模问题时&#xff0c;你是否曾经感到茫然无措&#xff1f;作为2022年美国大学生数学建模比赛的O奖得主&#xff0c;我为大家提供了一套优秀的解题思路&#xff0c;让你轻松应对各种难题。 问题一&#xff1a; 建立没有作物的玻璃温室内的温度和风速分…

【每日OJ —— 20.有效的括号(栈)】

每日OJ —— 20.有效的括号&#xff08;栈&#xff09; 1.题目&#xff1a;20.有效的括号&#xff08;栈&#xff09;2.方法讲解2.1.解法2.1.1.算法讲解2.1.2.代码实现2.1.3.提交通过展示 1.题目&#xff1a;20.有效的括号&#xff08;栈&#xff09; 2.方法讲解 2.1.解法 利用…

Mysql中正则表达式Regexp常见用法

Mysql中正则表达式Regexp常见用法_regexp不包含-CSDN博客

设计模式——RBAC 模型详解

1.什么是 RBAC 呢&#xff1f; RBAC 即基于角色的权限访问控制&#xff08;Role-Based Access Control&#xff09;。这是一种通过角色关联权限&#xff0c;角色同时又关联用户的授权方式。 简单地说&#xff1a;一个用户可以拥有若干角色&#xff0c;每一个角色又可以被分配…

nint和Pattern matching介绍(C#)

nint 最近看C# 9.0时&#xff0c;发现一个有意思的关键词&#xff0c;就是nint&#xff0c;第一次看到这个&#xff0c;于是好奇心爆棚&#xff0c;就去实际操作了一下。 nint i 1000; Console.WriteLine("i{0}", i);实际结果与int的结果是一样的&#xff0c;那为什…

PHP中间件实现

目录 1、简单中间实现 2、使用闭包函数实现中间件 在PHP中&#xff0c;中间件是一种常用的设计模式&#xff0c;用于处理请求和响应&#xff0c;它可以在请求到达目标处理程序之前或响应发送给客户端之前执行一些特定的逻辑。中间件提供了一种灵活的方式来修改或扩展应用程序的…