【Java版oj】day29求正数数组的最小不可组成和、有假币

news/2024/11/26 5:56:44/

目录

 一、求正数数组的最小不可组成和

(1)原题再现

(2)问题分析

(3)完整代码

 二、有假币

(1)原题再现

(2)问题分析

(3)完整代码


 一、求正数数组的最小不可组成和

(1)原题再现

求正数数组的最小不可组成和_百度笔试题_牛客网
        给定一个全是正数的数组arr,定义一下arr的最小不可组成和的概念: 1,arr的所有非空子集中,把每个子集内的所有元素加起来会出现很多的值,其中最小的记为min,最大的记为max; 2,在区间[min,max]上,如果有一些正数不可以被arr某一个子集相加得到,那么这些正数中最小的那个,就是arr的最小不可组成和; 3,在区间[min,max]上,如果所有的数都可以被arr的某一个子集相加得到,那么max+1是arr的最小不可组成和; 举例: arr = {3,2,5} arr的min为2,max为10,在区间[2,10]上,4是不能被任何一个子集相加得到的值中最小的,所以4是arr的最小不可组成和; arr = {3,2,4} arr的min为2,max为9,在区间[2,9]上,8是不能被任何一个子集相加得到的值中最小的,所以8是arr的最小不可组成和; arr = {3,1,2} arr的min为1,max为6,在区间[2,6]上,任何数都可以被某一个子集相加得到,所以7是arr的最小不可组成和; 请写函数返回arr的最小不可组成和。

(2)问题分析

      其实这就是一道找寻所有组合可能的情况的题。

      例如数组{3,2,4},可能的集合为{3},{2},{4},{3,2},{3,4},{2,4},{3,2,4}(不包含空集)。得到的和经过排序为2,3,4,5,6,7,9。8不在连续的当中,所以输出8。

       这里我其实利用了动态规划的思想,但是没有用状态方程求解,而是遍历寻找 。我们知道Set集合有去重的功能,所有我们就用这个保存所有组合情况的和。首先第一步先将0 添加进集合,每次将数组中一个数与集合中的每一个数进行求和运算,并把结果放在队列中。还以数组{3,2,4}为例,第一个数3与0进行运算,此时队列中就有3。队列不为空,删去队列中的数并将其放入集合中。这时,集合里就有0,3。其次第二步将数组中下一个数与集合中的每一个数进行求和运算,2+0=2,2+3=5,加入队列,删除队列中元素加入集合。接着第三步将数组中下一个数与集合中的每一个数进行求和运算,4+0=0,4+3=7,4+2=6,4+5=9。最后数组遍历完毕,删去s集合中一开始加入的0。

        大家可能疑惑的点,如果数组里有0,set又有去重功能,最后再把0删去不就少了一种情况嘛?这种可能是不可能的,因为题目要求全是正数。

        第二要额外定义一个链表,不能直接加入集合吗,当然不行,set集合的循环在内层,如果每次都直接加入进去,set集合的长度就不断的在改变。造成死循环。

(3)完整代码

import java.util.*;/** 求正数数组的最小不可组成和*/
public class Solution {public int getFirstUnFormedNum(int[] arr) {Set <Integer> set = new HashSet<>();Deque <Integer>queue = new LinkedList<>();int len = arr.length;set.add(0);for (int i = 0; i < len; i++) {for (int j : set) {queue.offer(arr[i] + j);}while (!queue.isEmpty()) {set.add(queue.poll());}}set.remove(0);Object[]setArr = set.toArray();Arrays.sort(setArr);int min = (int)setArr[0];int max = (int)setArr[setArr.length - 1];for (int k = min; k <= max; k++) {if (!set.contains(k)) {return k;}}return max + 1;}
}

 二、有假币

(1)原题再现

有假币__牛客网

居然有假币! 现在猪肉涨了,但是农民的工资却不见涨啊,没钱怎么买猪肉啊。nowcoder这就去买猪肉,结果找来的零钱中有假币!!!可惜nowcoder 一不小心把它混进了一堆真币里面去了。只知道假币的重量比真币的质量要轻,给你一个天平(天平两端能容纳无限个硬币),请用最快的时间把那个可恶的假币找出来。

 

输入描述:

1≤n≤2^30,输入0结束程序。

 

输出描述:

最多要称几次一定能把那个假币找出来?

示例1

输入

3

12

0

输出

1

3

(2)问题分析

        是很经典的一道题目。不是用二分法,而是每次都将硬币分成3份。我感觉第一次很难有人直接想出来要分三次。

对于 1个硬币,称量 0次。
对于 2个硬币,称量 1次。
对于 3个硬币,称量 1次。
对于 4个硬币,称量 2次,先分成(2,2,0),第一次称量前两份(2,2),如果重量不一样,再次求出判断另外2个硬币需要称量的次数。
对于 5个硬币,称量 2次,先分成(2,2,1),第一次称量前两份(2,2),如果重量不一样,再次判断另外1个硬币需要称量的次数。
对于 6个硬币,称量 2次,先分成(2,2,2),第一次称量前两份(2,2),如果重量不一样,再次判断求出另外2个硬币需要称量的次数。
对于 7个硬币,称量 2次,先分成(3,3,1),第一次称量前两份(3,3),如果重量不一样,再次判断求出另外3个硬币需要称量的次数。
        每次都将称量的硬币分成3份,要求前两份的个数不小于第三份。如果前两份重量是一样,则假币在第三份中,这样可以除去2/3的硬币;如果前两份重量不一样,那么假币在重量轻的一份中,这样也可以除去2/3的硬币。

(3)完整代码

import java.util.Scanner;
import java.util.zip.CheckedOutputStream;/** 有假币*/
public class Main {public static void main(String[] args) {Scanner sc = new Scanner(System.in);while (sc.hasNextInt()) {int n = sc.nextInt();if (n == 0) {return ;}System.out.println(fun(n));}}public static int fun(int n) {int count = 0;if (n == 1) {return 0;}if (n <= 3) {return 1;}int part = (n + 2) / 3;int left = n - part * 2;count = Math.max(fun(part), fun(left)) + 1;return count;}
}



http://www.ppmy.cn/news/43125.html

相关文章

准备2023(2024)蓝桥杯

前缀和 一维前缀和 s[i]s[i-1]a[i]二维前缀和&#xff08;子矩阵的和&#xff09; s[i][j]s[i-1][j]s[i][j-1]-s[i-1][j-1]a[i][j] 差分 一维数组 //b是差分数组b[i]c;b[j1]-c;例题 #include<iostream> using namespace std; int n,m; int b[100002],a[100002]; vo…

凌恩生物文献分享|微刊:三代全长16s扩增子——环境多样性研究的明星

在微生物研究领域&#xff0c;PacBio三代全长的时代已经来临&#xff0c;如果你还没用过那就太可惜了&#xff01; 要问三代有什么好&#xff0c;那我可得说道说道。 相比于传统二代Illumina平台测序&#xff0c;PacBio Sequel lle 平台获得的序列更长&#xff0c;信息量更多…

前端 icon 方案该升级了

说到 icon&#xff0c;很多前端开发只能想到 iconfont&#xff0c;或者组件库中提供的那些图标&#xff0c;当然这对于绝大多数开发场景是够用的。 但要知道&#xff0c;iconfont 的方案其实是在 2016 年公开&#xff0c;到现在也已经有 6 年之久&#xff0c;它确实在这一段时…

JS实用技巧断点调试详解

调试能力是一个程序员的生存根本&#xff0c;可是很多初学者却忽视调试。今天我们就来讨究一下JS的调试技巧。本文章将会详细列举JS相关的各种实用调试技巧。 如果您是JS的初学者&#xff0c;那么这篇文章将对您有很大的帮助。为什么要调试&#xff1f;程序就是函数堆砌起来的…

gdb调试技巧

GDB是GNU Debugger的缩写&#xff0c;是一款常用的命令行调试器&#xff0c;可用于调试C、C、汇编等程序。以下是一些常用的GDB调试技巧&#xff1a; 启动GDB&#xff1a;使用命令行启动GDB&#xff0c;如下所示&#xff1a; gdb <program>其中<program>是要调试的…

html的重绘和回流

HTML 的渲染是由浏览器进行的&#xff0c;当浏览器加载 HTML 文档并构建出 DOM 树后&#xff0c;将会进入到渲染流程。在这个过程中&#xff0c;浏览器需要进行两个关键操作&#xff1a;回流(reflow)和重绘(repaint)。 回流和重绘都是浏览器为了更新页面而进行的操作&#xff…

算法模板(2):数据结构(3) 复杂数据结构1

复杂数据结构&#xff08;1&#xff09; 1. Splay 基本概念 什么是 Splay Splay 是一种二叉查找树&#xff0c;它通过不断将某个节点旋转到根节点&#xff0c;使得整棵树仍然满足二叉查找树的性质&#xff0c;并且保持平衡而不至于退化为链. 旋转操作 为了使 Splay 保持平…

基于PCA与LDA的数据降维实践

基于PCA与LDA的数据降维实践 描述 数据降维&#xff08;Dimension Reduction&#xff09;是降低数据冗余、消除噪音数据的干扰、提取有效特征、提升模型的效率和准确性的有效途径&#xff0c; PCA&#xff08;主成分分析&#xff09;和LDA&#xff08;线性判别分析&#xff0…