[蓝桥杯] 挖矿(CC++双语版)

article/2025/6/26 3:35:07

题目链接

          P10904 [蓝桥杯 2024 省 C] 挖矿 - 洛谷

题目理解

        我们可以将这道题中矿洞的位置理解成为一个坐标轴,以题目样例绘出坐标轴:

样例:

        输入的5为矿洞数量,4为可走的步数。第二行输入是5个矿洞的坐标。输出结果为在要求步数内最多可采集到的单位数量的矿石。

         我们下面来对样例进行分析:

        初始状态如下:

        初始位置为0,剩余步数为4。当坐标0有矿石时,不需要消耗步数,可直接获取矿石:

        我们向-1移动:

        此时若是向负轴移动,我们只能采到1个单位的矿石,正轴方向可以采到2个单位。于是我们向正轴方向进发:

        继续进发:

        继续:

 

解题思路

      ——(篇幅较长,大家也可以先看详细注释后的代码,遇到不懂的地方再看解题思路)——

   一、核心思路概述

        解决该挖矿问题的核心在于合理利用数轴上矿洞的分布信息以及移动距离限制,通过巧妙的统计和计算,找出在给定移动距离内能够挖掘到最多矿石的方法。主要步骤包括对矿洞坐标的分类统计、构建前缀和数组以快速计算区间矿洞数量,以及全面考虑不同移动策略下的矿石获取情况。

   二、具体步骤解析

    (一)输入数据处理

1. 读取矿洞数量 n 和最大移动距离 m,这两个参数将决定后续计算的范围和约束条件。

2. 依次读取 n 个矿洞在数轴上的坐标值,对于每个坐标值进行如下分类处理:

  •         如果坐标值为 0,说明该矿洞位于小蓝的起始位置,直接将此类矿洞的计数变量 s 加 1。这些矿洞无需移动即可挖掘,对最终结果有直接贡献。
  •         如果坐标值不为 0,且其绝对值小于等于 m,则根据坐标值的正负性分别处理。
  •         若坐标值为负数,将其对应在负半轴的位置索引处的计数器(例如数组 l)加 1,用于统计负半轴上在移动距离范围内的矿洞数量。
  •         若坐标值为正数,将其对应在正半轴的位置索引处的计数器(例如数组 r)加 1,用于统计正半轴上在移动距离范围内的矿洞数量。

  (二)构建前缀和数组

        1. 对于记录负半轴矿洞数量的数组 l,从索引 1 开始到 m,依次计算前缀和。即 l[i] = l[i - 1] + l[i],这样 l[i] 就表示数轴负半轴上从 -1 到 -i 位置的矿洞总数。通过前缀和,我们可以在后续计算中快速得到负半轴某一区间内的矿洞数量。

        2. 同理,对于记录正半轴矿洞数量的数组 r,也从索引 1 开始到 m,计算前缀和 r[i] = r[i - 1] + r[i],使得 r[i] 表示数轴正半轴上从 1 到 i 位置的矿洞总数。

  (三)计算最大矿石获取量

1. 初始假设:

  •         首先假设最大矿石获取量 ans 为只在正半轴或只在负半轴移动时能够挖掘到的最大矿石数。即 ans = max(r[m], l[m]),这是一种简单的初步情况考虑,因为在某些情况下,仅在一个方向移动可能就能够获取最多的矿石。

2. 考虑混合移动策略:

  •         通过循环遍历 i 从 1 到 m / 2(因为左右移动距离之和不能超过 m,所以 i 最大取到 m / 2),尝试不同的左右移动组合。 - 对于每一个 i 值,计算两种混合移动策略下能够挖掘到的矿石数:
  •         先向右移动 i 单位距离,再向左移动 m - 2 * i 单位距离时,能够挖掘到的矿石数为 sr = r[i] + l[m - 2 * i]。这里 r[i] 表示向右移动 i 单位距离过程中挖掘到的正半轴矿洞数,l[m - 2 * i] 表示向左移动 m - 2 * i 单位距离过程中挖掘到的负半轴矿洞数。 - 先向左移动 i 单位距离,再向右移动 m - 2 * i 单位距离时,能够挖掘到的矿石数为 sl = l[i] + r[m - 2 * i]。这里 l[i] 表示向左移动 i 单位距离过程中挖掘到的负半轴矿洞数,r[m - 2 * i] 表示向右移动 m - 2 * i 单位距离过程中挖掘到的正半轴矿洞数。
  •         每次计算出 sr 和 sl 后,更新最大矿石获取量 ans,即 ans = max(ans, sr, sl),取当前的 ans、sr 和 sl 中的最大值作为新的 ans。

3. 加上起始点矿洞数量:

  •         最后,将起始点(坐标为 0)的矿洞数量 s 加到 ans 中,因为这些矿洞在初始位置就可获取,无需移动。此时得到的 ans 即为在移动距离不超过 m 的前提下,小蓝最多能获得的矿石单位数量。 通过以上步骤,我们可以全面且高效地解决在给定条件下的挖矿问题,找到获取最多矿石的方案。

完整代码(详细注释)

        本文由于用到了std库中的一些函数,所以作者最开始采用了C++,C语言代码作者用ai转化并确保代码无误后给大家放在了下面。

    1.C++代码

#include <bits/stdc++.h>// 定义 solve 函数来解决挖矿问题
void solve() 
{int n, m;// 从标准输入读取矿洞数量 n 和最大移动距离 mstd::cin >> n >> m;// s 用于记录坐标为 0 的矿洞数量int s = 0;// 定义两个静态数组 l 和 r 来分别记录负半轴和正半轴矿洞的前缀和// 数组大小为 m + 1,初始化为 0int l[10000001] = {0};int r[10000001] = {0};// 遍历每个矿洞for (int i = 0; i < n; ++i) {int x;// 读取当前矿洞的坐标std::cin >> x;// 如果矿洞坐标的绝对值小于等于最大移动距离 m 且为负数//abs为绝对值函数if (std::abs(x) <= m && x < 0){// 对应负半轴的位置计数加 1l[-x]++;}// 如果矿洞坐标的绝对值小于等于最大移动距离 m 且为正数else if (std::abs(x) <= m && x > 0) {// 对应正半轴的位置计数加 1r[x]++;}// 如果矿洞坐标为 0else if (x == 0) {// 坐标为 0 的矿洞数量加 1s++;}}// 计算负半轴矿洞的前缀和for (int i = 1; i <= m; ++i){l[i] += l[i - 1];}// 计算正半轴矿洞的前缀和for (int i = 1; i <= m; ++i) {r[i] += r[i - 1];}// 先假设最大矿石数为只走正半轴或只走负半轴能挖到的最大矿石数int ans = std::max(r[m], l[m]);// 尝试不同的左右移动组合,i 表示先向一个方向移动的距离for (int i = 1; i <= m / 2; ++i) {// 先向右移动 i 的距离,再向左移动 m - i * 2 的距离能挖到的矿石数int sr = r[i] + l[m - i * 2];// 先向左移动 i 的距离,再向右移动 m - i * 2 的距离能挖到的矿石数int sl = l[i] + r[m - i * 2];// 更新最大矿石数ans = std::max({ans, sr, sl});}// 加上坐标为 0 的矿洞数量ans += s;// 输出最大能获得的矿石数std::cout << ans << '\n';
}int main() 
{solve();return 0;
}

     2.C语言代码 

#include <stdio.h>
#include <math.h>#define MAX_M 10000001// 定义 solve 函数来解决挖矿问题
void solve() {int n, m;// 从标准输入读取矿洞数量 n 和最大移动距离 mscanf("%d %d", &n, &m);// s 用于记录坐标为 0 的矿洞数量int s = 0;// 定义两个静态数组 l 和 r 来分别记录负半轴和正半轴矿洞的前缀和// 数组大小为 MAX_M,初始化为 0int l[MAX_M] = {0};int r[MAX_M] = {0};// 遍历每个矿洞for (int i = 0; i < n; ++i) {int x;// 读取当前矿洞的坐标scanf("%d", &x);// 如果矿洞坐标的绝对值小于等于最大移动距离 m 且为负数if (abs(x) <= m && x < 0) {// 对应负半轴的位置计数加 1l[-x]++;}// 如果矿洞坐标的绝对值小于等于最大移动距离 m 且为正数else if (abs(x) <= m && x > 0) {// 对应正半轴的位置计数加 1r[x]++;}// 如果矿洞坐标为 0else if (x == 0) {// 坐标为 0 的矿洞数量加 1s++;}}// 计算负半轴矿洞的前缀和for (int i = 1; i <= m; ++i) {l[i] += l[i - 1];}// 计算正半轴矿洞的前缀和for (int i = 1; i <= m; ++i) {r[i] += r[i - 1];}// 先假设最大矿石数为只走正半轴或只走负半轴能挖到的最大矿石数int ans = (r[m] > l[m]) ? r[m] : l[m];// 尝试不同的左右移动组合,i 表示先向一个方向移动的距离for (int i = 1; i <= m / 2; ++i) {// 先向右移动 i 的距离,再向左移动 m - i * 2 的距离能挖到的矿石数int sr = r[i] + l[m - i * 2];// 先向左移动 i 的距离,再向右移动 m - i * 2 的距离能挖到的矿石数int sl = l[i] + r[m - i * 2];// 更新最大矿石数if (sr > ans) ans = sr;if (sl > ans) ans = sl;}// 加上坐标为 0 的矿洞数量ans += s;// 输出最大能获得的矿石数printf("%d\n", ans);
}int main() {solve();return 0;
}

       AC拿下!

疑难解答 

    1.max函数的运用

        用于比较出几个数中最大的数字,大家可以简单理解为两个数比较就不需要大括号,如果三个及以上的话需要大括号。

  • 两个参数比较:当比较两个值时,使用 std::max(a, b) 形式,这里 a 和 b 是要比较的对象,不需要大括号。比如 int num1 = 5, num2 = 3; int maxNum = std::max(num1, num2); 。
  • 三个及以上参数比较:对于三个或更多值,常使用接收初始化列表形式的重载,即 std::max({val1, val2, val3,...}) ,需要用大括号把这些值组成初始化列表传递给函数。像 int num1 = 1, num2 = 2, num3 = 3; int maxNum = std::max({num1, num2, num3}); 。

———(如有问题,欢迎评论区提问)———


http://www.hkcw.cn/article/fEyXEiVtRo.shtml

相关文章

【C语言】 —— 预处理详解(下)

【C语言】 —— 预处理详解&#xff08;下&#xff09; 前言七、# 和 \##7.1 # 运算符7.2 ## 运算符 八、命名约定九、# u n d e f undef undef十、命令行定义十一、条件编译11.1、单分支的条件编译11.2、多分支的条件编译11.3、判断是否被定义11.4、嵌套指令 十二、头文件的包…

C/C++ 内存管理深度解析:从内存分布到实践应用(malloc和new,free和delete的对比与使用,定位 new )

一、引言&#xff1a;理解内存管理的核心价值 在系统级编程领域&#xff0c;内存管理是决定程序性能、稳定性和安全性的关键因素。C/C 作为底层开发的主流语言&#xff0c;赋予开发者直接操作内存的能力&#xff0c;却也要求开发者深入理解内存布局与生命周期管理。本文将从内…

VS Studio2022安装教程(保姆级教程)

1.下载 官网下载&#xff1a; Visual Studio 2022 IDE - 适用于软件开发人员的编程工具 (microsoft.com)https://visualstudio.microsoft.com/zh-hans/vs/ 1.点击下载Community2022(社区版),等待下载完成之后,运行安装包&#xff08;VisualstudioSetup.exe&#xff09; 2.等待…

【CSAPP】【attacklab】实验三 Attack lab 详解

前置知识 call 指令 ret 指令 寄存器rip 栈 小端模式 栈向下生长&#xff0c;栈顶在低地址&#xff0c;栈底在高地址 指令寄存器&#xff08;RIP&#xff09;包含下一条将要被执行的指令的逻辑地址。 通常情况下&#xff0c;每取出一条指令后&#xff0c;RIP会自增指向下一…

【C/C++】字符函数和字符串函数

文章目录 前言字符函数和字符串函数1.字符分类函数2.字符转换函数3.strlen的使用和模拟实现3.1 代码演示3.2 strlen返回值3.3 strlen的模拟实现 4.strcpy的使用和模拟实现4.1 代码演示4.2 模拟实现 5.strcat的使用和模拟实现5.1 代码演示5.2 模拟实现 6.strcmp的使用和模拟实现…

C/C++之内存管理

1. 内存分布 我们定义的变量对于电脑来说也叫数据&#xff0c;同时电脑也会把这些数据分为不同的类型&#xff0c;分别是局部数据&#xff0c;静态数据&#xff0c;全局数据&#xff0c;常量数据和动态申请数据。 在 C 中&#xff0c;各类数据存储位置如下&#xff1a; • 局…

C++从入门到实战(十一)详细讲解C/C++语言中内存分布与C与C++内存管理对比

C从入门到实战&#xff08;十一&#xff09;详细讲解C/C语言中内存分布与C与C内存管理对比 前言一、C/C语言中内存分布1.内核空间2.栈3.堆4.数据段5.代码段 二、例题带练巩固C/C语言中内存分布的知识题目讲解题目答案 三、C语言动态内存分配&#xff08;知识回顾&#xff09;3.…

Educational Codeforces Round 175 (C.二分 D.树形结构、dp)

文章目录 2025.3.3C. Limited Repainting(二分)题意思路代码 D. Tree Jumps(树形结构、dp)题意思路代码 2025.3.3 Educational Codeforces Round 175 (Rated for Div. 2) C. Limited Repainting(二分) 题意 给出一个字符串a由“R”B“组成&#xff0c;不同位置对应一个惩罚…

老太突然倒地吓坏路人民警紧急相救 家属感激救命之恩

“谢谢你们帮我父亲‘捡’回一条命,再晚一会儿后果不堪设想!”5月21日,市民刘女士接到民警电话时再次表达了对紧急救援的感激之情。她的父亲76岁,患有阿尔兹海默病,下午扛着锄头出门后一直未归,家人找了3个多小时都没找到。5月19日傍晚6时许,大冶市公安局还地桥派出所接…

53岁男子诱骗侵害幼女被判刑 深挖彻查揭露更多罪行

5月29日,江苏省人民检察院召开新闻发布会,介绍了近年来加强未成年人网络司法保护的工作情况及典型案例。如皋市检察院副检察长卢海琴介绍了一起典型案例,通过深挖彻查,案件从1名被告人追到3名被告人、从1个罪名查到5个罪名、从1起强奸事实挖到19起犯罪事实、从1名被害人增加…

谷歌DeepMind最强手语翻译模型登场 打破沟通障碍

谷歌DeepMind团队于5月27日宣布推出SignGemma,这是其迄今为止最强大的手语翻译模型,能够将手语转化为口语文本。该开源模型计划在今年晚些时候加入Gemma模型家族。SignGemma支持多语言功能,但目前主要针对美国手语(ASL)和英语进行了深度优化,开发者可以自由使用并改进它。…

【C++】STL详解-----(二)vetor的使用

文章目录 vector的介绍vector的使用&#xff1a;元素访问empty vector的增删查改push_back和pop_backinsert和erase vector迭代器失效问题迭代器失效解决方法 vector的介绍 vector是可变大小数组的容器vector采用连续空间存储的方式&#xff0c;同时也表示可以采用下标访问vec…

string类

1. 为什么学习string类&#xff1f; string叫串&#xff0c;它是一个管理字符串的类&#xff0c;现实中为什么要出一个管理字符串的类呢&#xff1f;现实中我们有很多类型&#xff0c;比如int、double、char等&#xff0c;但发现这个世界的一些复杂东西都是通过字符串表示的…

潍坊烟花秀压轴项目缺席遭吐槽 设备故障引争议

多名网友在社交平台发帖表示,5月30日晚他们参加了潍坊世界风筝乐园的烟花秀表演,单人票198元,双人票298元。然而,之前宣传的压轴项目“七彩祥云”并未出现,引发观众不满。潍坊世界风筝乐园工作人员解释称,由于设备故障,“七彩祥云”环节被迫取消,并且当晚和接下来两天的…

江苏城市足球联赛为何这么火 赛事带动文旅热潮

最近,2025年江苏省城市足球联赛“苏超”火了。从“比赛第一,友谊第十四”到各地纷纷推出“跟着赛事游江苏”的文旅优惠,以足球为媒,以赛事为桥,江苏展现了独特的魅力。自5月10日揭幕以来,“苏超”迅速走红,成为江苏省乃至全国关注的热点。你以为“苏超”只是踢踢比赛?殊…

汪涵体验问界M9五座零重力座椅 舒适到不想起

汪涵体验了问界M9的零重力座椅,表情十分享受。这款座椅采用零压感知人体工学专利设计,腰部零压角为121,腿部零压角为136,能够使全身压力均匀分布,带来零压悬浮感。汪涵坐在上面久久不愿起身,甚至在车展主持时也选择躺着进行,这种舒适度让人非常心动。责任编辑:0882

德国为何要解除对援乌武器射程限制 西方军援策略重大转变

2025年5月28日,德国新当选总理弗里德里希默茨在柏林宣布,乌克兰的西方盟友将取消向基辅供应武器的射程限制。这一政策调整涵盖美国、英国、法国和德国等主要援乌国家,标志着西方对乌军援策略的重大转变,随即引发国际社会对俄乌冲突走向的强烈关注。在WDR组织的论坛上,默茨…

Nginx基础篇(Nginx目录结构分析、Nginx的启用方式和停止方式、Nginx配置文件nginx.conf文件的结构、Nginx基础配置实战)

文章目录 1. Nginx目录结构分析1.1 conf目录1.2 html目录1.3 logs目录1.4 sbin目录 2. Nginx的启用方式和停止方式2.1 信号控制2.1.1 信号2.1.2 调用命令 2.2 命令行控制2.2.1 基础操作类2.2.2 配置测试类2.2.3 进程控制类2.2.4 路径与文件类2.2.5 高级配置类 3. Nginx配置文件…

印军高层被追问是否与巴方会面 印空军将领打马虎眼

印巴停火协议签署后,两国都在宣称自己取得了胜利。然而,印度军方的表现却让人失望。5月11日,印度空军中将巴蒂召开记者会,面对记者们的追问,他声称印度空军在这次冲突中表现出色,并坚称打下了好几架巴基斯坦飞机。但当被问及具体数字时,他却表示“不想冒险猜测”,并解释…

大V:辽宁舰率海军最强编队驶入西太 展现惊人实力

自去年10月在南海与山东舰稍微展示了一下双航母的实力后,辽宁舰到今年5月中旬都没有什么动作,大家的目光都放在了更出色的山东舰和福建舰上。然而,辽宁舰在5月下旬南下西太平洋,展示了强大的实力。护航编队包括两艘055型驱逐舰、五艘052D型驱逐舰和三艘054A型护卫舰,再加上…