2023年第十四届蓝桥杯JavaB组省赛真题及全部解析(下)

承接上文:2023年第十四届蓝桥杯JavaB组省赛真题及全部解析(下)。

目录

七、试题 G:买二赠一

八、试题 H:合并石子 

九、试题 I:最大开支

十、试题 J:魔法阵


题目来自:蓝桥杯官网

七、试题 G:买二赠一

• 题目分析:

因为每次我们要尽可能的使免费拿走商品的价格尽可能的大,但是免费的金额又与较便宜的物品有关,这是一道贪心题(猜的,比赛想到就可以写了,贪心的证明是非常恶心的)。

• 解题思路:

1. 排序商品价格(降序)。

2. 使用队列来存储免费的金额。

3. 遍历全部商品,遇到能免费的商品(小于队列队头元素),出队列,这个商品跳过(不加到总和)。其他的正常遍历,加到总和。

4. 一旦选了两个商品,将后面选的(肯定小于前面选的)一半价格加入队列。

5. 返回结果。

如果下面的排序写法看不懂的话,可以去看我之前写的Java sort 详解,里面都有写到。

• 代码编写:

import java.util.*;
public class Main{public static void main(String[] args) {Scanner in = new Scanner(System.in);int n = in.nextInt();//读入数据Integer[] arr = new Integer[n];for(int i = 0;i < n;i++){arr[i] = in.nextInt();}Arrays.sort(arr,(o1,o2) -> {//从大到小排序return o1 >= o2 ? -1 : 1;//或者(o2 - o1)});long sum = 0;//存储总花费Queue<Integer> q = new LinkedList<>();//存储可以免费的金额,保证是先进先出int count = 0;//记录何时到达二次for(int i = 0;i < n;i++){if(!q.isEmpty() && q.peek() >= arr[i]) {//说明可以免费带走q.poll();//队头免费金额用过了,把队头弹出去。continue;//跳过这个商品}sum += arr[i];count++;if(count == 2){count = 0;q.add(arr[i] / 2);//可以免费的金额,存入队列}}System.out.println(sum);}
}

• 运行结果: 

八、试题 H:合并石子 

• 题目分析:

这是一道区间 dp 的问题,关于区间 dp 可能平时会遇到的比较少。如果不了解的话,建议先去看看区间 dp,再去洛谷把 合并石子 (这道题的简化版)做了。

• 解题思路:

1. 状态表示:

dp[i][j][k]:表示合并区间[i , j]为 1 堆,且颜色为 k 的最小花费。

其他的参数说明:

sum[i]:表示前 i 堆石头的和(前缀和方便后续求值)。

cost[ij][j]:表示从在区间[ i ,j ]的最小花费(dp表示的是 1 堆,最后结果不一定为 1 堆,所以要重新创建一个)。

nums[i][j]:表示在区间[ i ,j ]的最小堆数。

2. 状态转移方程:

dp[i][j][(k + 1) % 3] 可以由分割点 j 的左边花费数 + 分割点 j 的右边花费数 + 合并两堆的花费数,转移过来。

dp[i][end][(k + 1) % 3] = Math.min(dp[i][end][(k + 1) % 3],dp[i][j][k] + dp[j + 1][end][k] + sum[end] - sum[i - 1]);

3.初始化:

把dp[ i ][ i ][col[ i ] ]初始为0,因为这本来就是 1 堆,不用合并花费。

其他的代码里面都有注释就不多赘述了。

• 代码编写:

import java.util.*;
public class Main {static int INF = 0x3f3f3f3f;public static void main(String[] args) {Scanner in = new Scanner(System.in);int n = in.nextInt();int[] col = new int[n + 1];//存储颜色int[] sum = new int[n + 1];//前缀和int[][] cost = new int[n + 1][n + 1];//表示i 到 j 区间的花费int[][] nums = new int[n + 1][n + 1];//区间的堆数//读入数据for(int i = 1;i <= n;i++){sum[i] = sum[i - 1] + in.nextInt();}for(int i = 1;i <= n;i++){col[i] = in.nextInt();}//初始化int[][][] dp = new int[n + 1][n + 1][3];for(int i = 1;i <= n;i++){for(int j = 1;j <= n;j++){nums[i][j] = j - i + 1;//独自成一堆Arrays.fill(dp[i][j],INF);//求最小值,防止被 0 干预}dp[i][i][col[i]] = 0;//只有自己且颜色存在}//填写 dp 表for(int len = 1;len <= n;len++){//枚举长度for(int i = 1;i + len - 1 <= n;i++){//枚举起点int end = i + len - 1;//找到终点for(int k = 0;k < 3;k++){//枚举颜色for(int j = i;j < end;j++){//枚举分割点if(dp[i][j][k] != INF && dp[j + 1][end][k] != INF){//去掉不存在的节点dp[i][end][(k + 1) % 3] = Math.min(dp[i][end][(k + 1) % 3],dp[i][j][k] + dp[j + 1][end][k] + sum[end] - sum[i - 1]);nums[i][end] = 1;//注意我们的状态就是表示合成一堆}}}}}//将堆数为 1 的花费填入 cost(只能填 1 )for(int i = 1;i <= n;i++){for(int j = i;j <= n;j++){if(nums[i][j] == 1){cost[i][j] = Math.min(dp[i][j][0],Math.min(dp[i][j][1],dp[i][j][2]));}}}//dp 表示是合成 1 堆,但是最后不一定能合成一堆,所以要再查找一次。//把所有区间都枚举出来,找到最小堆数的最小花费for(int k = 1;k <= n;k++){for(int i = 1;i <= k;i++){for(int j = k + 1;j <= n;j++){if(nums[i][j] > nums[i][k] + nums[k + 1][j]){nums[i][j] = nums[i][k] + nums[k + 1][j];cost[i][j] = cost[i][k] + cost[k + 1][j];}else if(nums[i][j] == nums[i][k] + nums[k + 1][j]){cost[i][j] = Math.min(cost[i][j],cost[i][k] + cost[k + 1][j]);}}}}System.out.println(nums[1][n] + " " + cost[1][n]);}
}

• 运行结果: 

九、试题 I:最大开支

 • 题目分析:

这题不能使用动态规划来做,因为时间复杂度至少为O(n^2),题目给出的数据为 10 ^ 5,会超时的,所以我们要另找方法。

考虑到H函数在乘于人数后,会变成一个一元二次方程 k * x ^ 2 + bx(k为负数);,开口向下,先递增后递减,并且递增的速度越来越慢,也就是说,随着项目参与人数的增加,总花费的增加(后一个减去前一个)会变得越来越少。因此我们贪心的点就来了,在往项目中增加人数时,我们每次都选取花费增加最多的项目添加。由局部最优,带来全局最优。

• 解题思路:

先算出一个花费增加数的公式:

我们配合优先级队列就能达到O(n * log(n))的时间复杂度。

• 代码编写:

import java.util.*;public class Main{static long sum = 0;//最初最终的总和static int[] k;static int[] b;static int[] cnt;//记录对应项目的人数static class Pair{//不能使用Java自带的,会遍历错误,很奇怪int key;//表示可以直接加到总和的花费int val;//表示第 val 个项目public Pair(int key,int val){this.key = key;this.val = val;}}public static void main(String[] args) {Scanner in = new Scanner(System.in);int n = in.nextInt(),m = in.nextInt();k = new int[m + 1];b = new int[m + 1];cnt = new int[m + 1];//大根堆PriorityQueue<Pair> q = new PriorityQueue<>((o1,o2) -> {return o1.key > o2.key ? -1 : 1;});//读入数据for(int i = 1;i <= m;i++){k[i] = in.nextInt();b[i] = in.nextInt();cnt[i] = 1;q.add(new Pair(mul(cnt[i],i),i));}for(int i = 0;i < n;i++){Pair tmp = q.poll();if(tmp.key <= 0){//小于0说明后续都小于0,直接退出即可break;}sum += tmp.key;Integer t = tmp.val;q.add(new Pair((k[t] * (2 * cnt[t] + 1) + b[t]),t));//推导出来的公式。cnt[t]++;//对应的人数 + 1}System.out.println(sum);}public static int mul(int x,int i){return (k[i] * x + b[i]) * x;//题目给出的公式}
}

 • 运行结果: 


十、试题 J:魔法阵

• 解题思路:

利用动态规划 + Dijkstra 算法的一些思想来做。

1. 状态表示:

dp[i][j]:表示从节点 0 到节点 i ,使用魔法消除最后 j 条边的最小总伤害。

2. 状态转移方程:

下面都是以 i 为终点,u 为起点来推的,w 为 u -> i 的权值。

• 不使用魔法:dp[i][0] = min(dp[i][0] , dp[u][0] + w);

• 使用魔法:dp[i][j] = min(dp[u][j - 1],dp[i][j]);其中 1<= j <= k。

• 魔法使用过了:dp[i][k] = min(dp[i][k] , dp[u][k] + w);

3. 初始化:

dp表除了 [0][0] 初始化为 0 ,其它的初始化为无穷大。

4. 填表:

配合 Dijkstra 算法进行填表。

5. 返回值:

返回 dp[n - 1][k]即可。

剩下的一些零碎在代码中都有注释。

• 代码编写:

import java.util.*;
public class Main {static class Pair<K,V>{//不能使用 Java 自带的,会编译不过去K v;V w;public Pair(K v,V w){this.v = v;this.w = w;}}public static void main(String[] args) {Scanner in = new Scanner(System.in);int n = in.nextInt(),k = in.nextInt(),m = in.nextInt();int INF = 0x3f3f3f3f;List<List<Pair<Integer,Integer>>> ret = new ArrayList<>();//使用邻接表的方式存储边for(int i = 0;i < n;i++){ret.add(new ArrayList<>());}//1.创建 dp 表int[][] dp = new int[n][k + 1];for(int i = 0;i < n;i++){Arrays.fill(dp[i],INF);}//2.初始化dp[0][0] = 0;for(int i = 0;i < m;i++){int u = in.nextInt(),v = in.nextInt(),w = in.nextInt();ret.get(u).add(new Pair<>(v,w));ret.get(v).add(new Pair<>(u,w));//无向图,所以两边都要存储边}//3.填表Queue<Integer> q = new LinkedList<>();//用来存放起点q.add(0);while(!q.isEmpty()){int u = q.poll();for(Pair<Integer,Integer> pair:ret.get(u)){//取出边
//                下面是 Dijkstra 算法的思路(不是完全一样)int v = pair.v;int w = pair.w;boolean flag = false;//表示还有没有从 v 节点为起点的必要,// 如果为 false 的话说明以 v 为起点绝对不是最小路径,要舍去,同时还可以防止死循环if(dp[v][0] > dp[u][0] + w){//选取最优flag = true;dp[v][0] = dp[u][0] + w;}for(int j = 1;j <= k;j++){if(dp[v][j] > dp[u][j - 1]){flag = true;dp[v][j] = dp[u][j - 1];}}if(dp[v][k] > dp[u][k] + w){flag = true;dp[v][k] = dp[u][k] + w;}if(flag == true){q.add(v);}}}//4.返回值
//        System.out.println(Math.min(dp[n - 1][0],dp[n - 1][k]));System.out.println(dp[n - 1][k]);//都行}
}

 • 运行结果:  

结语:

其实写博客不仅仅是为了教大家,同时这也有利于我巩固知识点,和做一个学习的总结,由于作者水平有限,对文章有任何问题还请指出,非常感谢。如果大家有所收获的话还请不要吝啬你们的点赞收藏和关注,这可以激励我写出更加优秀的文章。

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

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

相关文章

【星海随笔】vue+vite

开头问一个问题&#xff0c;我发现有的人粉丝是点赞数的好几倍&#xff0c;可能和必须关注他才能阅读他的文章有关。 所以问一下怎么设置为关注才能查看该文章。 screen -ls #查看 id 列表 screen -S <session_name> # 创建一个会话 screen -R <session_id> # 根据…

iconfont-阿里巴巴矢量图标库 在vue项目使用记录

官网地址&#xff1a;https://www.iconfont.cn/manage/index?manage_typemyprojects&projectId4539761 第一步&#xff1a; 下载资源 ->解压到项目文件夹 第二步 在项目中main.ts 或者main.js 引入资源 import //assets/iconfont/font/iconfont.js; import //assets…

IBM Spectrum LSF RTM,针对 IBM Spectrum LSF 环境的高级报告、跟踪和监控工具

亮点 为 IBM Spectrum LSF 环境提供性能监控和报告 监控 FlexNet Publisher 和 Reprisebased 许可证的使用&#xff0c;提供详细和总结性报告 通过多个级别&#xff08;包括应用程序和组织&#xff09;的报告来监控共享存储的利用率 提供强大的生产力工具&#xff0c;包括操…

JVM专题五:类加载器与双亲委派机制

通过上一篇Java的类加载机制相信大家已经搞明白了整个类加载从触发时机&#xff0c;接着我们就来看下类加载器&#xff0c;因为类加载机制是有加载器实现的。 类加载器的分类 启动类加载器 Bootstrap ClassLoader 是 Java 虚拟机&#xff08;JVM&#xff09;的一部分&#x…

斜光测距的原理及python实现

1.前言 最近做了一个基于opencv的斜光测距的小项目&#xff0c;东西不多&#xff0c;但是很有意思&#xff0c;值得拿出来学一学。项目里面需要比较精确的定位功能&#xff0c;将前人matlab代码移植到python上&#xff0c;并且做了一些优化&#xff0c;简化逻辑(毕竟我是专业的…

我教会了我妈搭建自己的 AI 聊天机器人...

在这个人工智能爆发的年代,ChatGPT、Claude、Kimi、文心一言等 AI 大模型产品火遍全网,仿佛一夜之间,人人都在谈论 AI。 作为普通人的我们,难道就只能看着程序员们尽情玩耍,自己却无法参与其中吗?NO! 鉴于最近自己社群学员和粉丝的要求&#xff0c;一进来大家无论是不是小白…

Linux防火墙【SNAT,DNAT】

NAT: 支持PREROUTING&#xff0c;INPUT&#xff0c;OUTPUT&#xff0c;POSTROUTING四个链 请求报文&#xff1a;修改源/目标IP&#xff0c; 响应报文&#xff1a;修改源/目标IP&#xff0c;根据跟踪机制自动实现 NAT的实现分为下面类型&#xff1a; SNAT&#xff1a;source…

如何实现数字人系统私有化部署?数字人源码部署教程简易版来了!

当前&#xff0c;数字人行业的市场前景和应用潜力不断显现&#xff0c;不少创业者都想要通过学习数字人源码部署教程来搭建属于自己的数字人系统&#xff0c;以此获得进军数字人行业的入场券。而事实上&#xff0c;该想法本身当然是固然值得鼓励的&#xff0c;但就目前的实践情…

基于改进天鹰优化算法(IAO)优化RBF神经网络数据回归预测 (IAO-RBF)的数据回归预测(多输入多输出)

改进天鹰优化算法(IAO)见&#xff1a;【智能优化算法】改进的AO算法(IAO)-CSDN博客 代码原理 基于改进天鹰优化算法&#xff08;IAO&#xff09;优化RBF神经网络数据回归预测&#xff08;IAO-RBF&#xff09;的多输入多输出&#xff08;MIMO&#xff09;数据回归预测&#xf…

视频去水印软件?在线去除视频水印工具网站?

视频去水印软件哪个好&#xff1f;在数字时代&#xff0c;视频内容的传播变得日益普遍&#xff0c;然而&#xff0c;许多视频带有水印&#xff0c;影响了观看体验&#xff0c;如果有这些图案我们需要找方法把这些图案从视频上去掉。今天我们就来看一下视频去水印的超级简单的方…

添加阈值滞后以实现平滑的欠压/过压锁定

电阻分压器将高压衰减到低压电路可以承受的水平&#xff0c;而不会过驱动或损坏。在电源路径控制电路中&#xff0c;电阻分压器有助于设置电源欠压和过压锁定阈值。这种电源电压鉴定电路存在于汽车系统、电池供电的便携式仪器以及数据处理和通信板中。 欠压锁定 (UVLO) 可防止…

goLang小案例-打印99乘法表

goLang小案例-打印99乘法表 1. 打印99乘法表 func Print99multiplication1() {//横向9排for i : 1; i < 9; i {//竖向9列//第一批第一个 和第一列比较 如果大于排就结束//假设第三排i3 最走有三列 1*3 2*3 3*3//j3打印完 j 当j4就要结束 以此类推for j : 1; j < i; j …

蓝牙耳机推荐学生党怎么选?300左右蓝牙耳机分享

在选择蓝牙耳机时&#xff0c;学生党需要考虑的因素包括音质、续航力、舒适度以及连接稳定性等&#xff0c;而在300元左右的价位&#xff0c;虽然不能期待与高端产品相媲美的性能&#xff0c;但依然有一些性价比较高的选择能够满足大部分的日常需求&#xff0c;下面给大家推荐几…

使用python基于经纬度获取高德地图定位地址【逆地址解析】

一、高德地图api申请 1. 高德开放平台注册&#xff0c;登录 进入网址&#xff1a;高德开放平台 | 高德地图API 注册 -- 支付宝扫码认证 -- 完善个人信息 -- 登录 2. 申请API &#xff08;1&#xff09;点击头像 -- 应用管理 -- 我的应用 -- 创建新应用 &#xff08;2&…

【papaparse插件】前端预览csv文件

需求&#xff1a;就是可以在前端直接预览csv文件的内容 1.了解csv文件 1.1 csv文件和xlsx、xls文件的异同 首先了解一下csv文件和excel文件&#xff08;xlsx&#xff0c;xls&#xff09;有什么异同&#xff0c;简单来说他们都是存储表格数据的文件&#xff0c;csv只能显示较…

一站式AI服务平台:MaynorAI助您轻松驾驭人工智能

一站式AI服务平台&#xff1a;MaynorAI助您轻松驾驭人工智能 在当前的数字化时代&#xff0c;人工智能&#xff08;AI&#xff09;技术已经成为推动各行各业创新发展的核心动力。为了更好地满足企业和个人用户对AI服务的需求&#xff0c;MaynorAI 作为一个领先的一站式调用国内…

【oracle】oracle索引分裂

本文为云贝教育 刘峰 原创&#xff0c;请尊重知识产权&#xff0c;转发请注明出处&#xff0c;不接受任何抄袭、演绎和未经注明出处的转载。 一、索引分裂概述 Oracle数据库中的索引分裂是数据库维护和性能管理中的一个重要概念&#xff0c;特别是在处理大量数据插入、更新和…

CVPR 2024最佳论文分享:生成图像动力学

CVPR 2024最佳论文分享&#xff1a;生成图像动力学 CVPR&#xff08;Conference on Computer Vision and Pattern Recognition&#xff09;是计算机视觉领域最有影响力的会议之一&#xff0c;主要方向包括图像和视频处理、目标检测与识别、三维视觉等。近期&#xff0c;CVPR 2…

2000—2022年青藏高原遥感生态指数数据集

该数据集是基于多套MODIS数据集&#xff0c;选取NDVI、LST、WET、NDBSI四项指标&#xff0c;采用主成分分析法&#xff0c;生成2000-2022年500米空间分辨率的遥感生态指数&#xff08;RSEI&#xff09;数据集。 遥感生态指数&#xff1a;是一种基于遥感技术的生态环境质量综合评…

3D立体卡片动效(附源码)

3D立体卡片动效 欢迎关注&#xff1a;xssy5431 小拾岁月参考链接&#xff1a;https://mp.weixin.qq.com/s/9xEjPAA38pRiIampxjXNKQ 效果展示 思路分析 需求含有立体这种关键词&#xff0c;我们第一反应是采用动画中的平移、倾斜等实现。如果是立体&#xff0c;必然产生阴影&…