蓝桥杯2021年第十二届国赛真题-巧克力

该博客讨论了一道编程题目,涉及如何帮助小蓝以最低成本购买足够吃x天的巧克力。关键策略是将巧克力按保质期从长到短排序,然后从后往前选择每天能吃的最便宜巧克力。博主提供了详细的解题思路和C++代码实现,通过优先队列动态维护每天的选择,确保找到最优解。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目描述

小蓝很喜欢吃巧克力,他每天都要吃一块巧克力。
一天小蓝到超市想买一些巧克力。超市的货架上有很多种巧克力,每种巧克力有自己的价格、数量和剩余的保质期天数,小蓝只吃没过保质期的巧克力,请问小蓝最少花多少钱能买到让自己吃 x 天的巧克力。

输入

输入的第一行包含两个整数 x, n,分别表示需要吃巧克力的天数和巧克力的种类数。
接下来 n 行描述货架上的巧克力,其中第 i 行包含三个整数 ai, bi, ci,表示第 i 种巧克力的单价为 ai,保质期还剩 bi 天(从现在开始的 bi 天可以吃),数量为 ci。

输出

输出一个整数表示小蓝的最小花费。如果不存在让小蓝吃 x 天的购买方案,输出ࠪ 1。

样例输入复制

10 3
1 6 5
2 7 3
3 10 10

样例输出复制

18

提示

【样例说明】
一种最佳的方案是第 1 种买 5 块,第 2 种买 2 块,第 3 种买 3 块。前 5 天
吃第 1 种,第 6、7 天吃第 2 种,第 8 至 10 天吃第 3 种。
【评测用例规模与约定】
对于 30% 的评测用例,n, x ≤ 1000。
对于所有评测用例,1 ≤ n, x ≤ 100000,1 ≤ ai, bi, ci ≤ 10^9。

解题思路:这个题给我的感觉有点像贪心,难点就在于如何选择贪心策略,如果我们按照正常思路,从第一天开始就选择能吃的巧克力,前面几天选择的范围比较大,到了后面几天就相对比较难选了,而且前面的选择会直接影响最后是否会有解以及解的大小,但是前面在选的时候我们根本无法对其造成的影响进行估计,举个例子:如果从前面开始选,一开始我们会面临很多种选择,我们通常会选择最优策略,也就是说保质期能满足当前这一天,并且价格最便宜,但如果存在这样一种巧克力,保质期最长,价格也是最低的,我们在一开始就把它给用了,到了后面就不能用了,也就是说它原本可以在很多天之后吃就行,现在却在前几天就吃了,吃的时候保质期还有很长的一段事件,到了后面可供选择的巧克力保质期就会越来越短,很可能会出现得不到一个可行方案的情况,对于这种情况,其实我们把前后选择的巧克力对调一下就能解决,把前面选的保质期长,价格低的巧克力放在后面吃,把后面价格高,保质期短的放在前面吃,通过这样一通分析,我们可以惊奇地发现,正着来不行,我们从后面来貌似就比较合理,这也就引申出了我们的正确的策略:

将所有种类的巧克力按保质期从长到短排序,然后我们从后面几天开始选择吃哪块巧克力,对于第i天,我们将所有保质期满足能在第i天吃的巧克力都找出来,然后对它们按价格从小到大排序,选择价格最低的在第i天吃,并记录一下这种巧克力已经用掉了几块,如果全部都用掉了,那就不能再用了,这里我们用到了优先队列来动态维护当天能吃的各种巧克力,用map来维护不同种类的巧克力已经用掉了几块。

上代码:

#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
#include <queue> 
#include <map>
using namespace std;
const int N=1e5+10;
struct node{
	long long a;
	long long b;
	long long c;
	int id;
}goods[N];
int x,n; 
map<int,int>mp;
bool cmp(struct node x1,struct node x2)
{
	return x1.b>x2.b;
}
struct cmp1{
	bool operator()(const node &p,const node &q)
	{
		return p.a>q.a;//从小到大排序 
	}
};
int main()
{
	cin>>x>>n;
	for(int i=1;i<=n;i++)
	cin>>goods[i].a>>goods[i].b>>goods[i].c,goods[i].id=i;
	sort(goods+1,goods+n+1,cmp);//按保质期从大到小排序 
	long long ans=0;
	priority_queue<node,vector<node>,cmp1>q;
    int j=1;
	for(int i=x;i>=1;i--)
	{
		while(goods[j].b>=i&&j<=n)//把所有能用的巧克力都找出来放到优先队列中 
		{
			q.push(goods[j]);
			j++;
		}
		if(!q.size())//如果中间某一天没有可以选择的巧克力,那就不存在一个合法的方案 
		{
			cout<<"-1"<<endl;
			return 0; 
		}
		node temp=q.top();
		mp[temp.id]++;
		ans+=temp.a;
		if(temp.c==mp[temp.id])//当前种类的巧克力已经全部用掉了,以后不能再用 
		q.pop();
	}
	cout<<ans<<endl;
	return 0;
}

### 关于蓝桥杯嵌入式第十四届真题 蓝桥杯作为内具有广泛影响力的技术竞平台,其嵌入式方向的比吸引了众多高校学生和技术爱好者的参与。针对第十四届蓝桥杯嵌入式真题资源,目前可以通过公开的学习资料获取相关信息[^2]。 #### 获取途径 1. **官方渠道** 官方网站通常会发布历的竞题目及相关文档。建议访问蓝桥杯官方网站并查找对应份的事信息。 2. **开源社区与学习平台** GitHub 和其他技术分享平台上可能存在由参者或教练上传的相关资源。例如,在某些仓库中可能找到标注清晰的第十四届蓝桥杯嵌入式真题文件。 3. **教育机构与学校支持** 许多高校和培训机构会在课程材料中加入历真题解析,尤其是针对准备参加比的学生群体。联系所在学校的指导教师可能是另一种有效的方式[^3]。 以下是基于 HAL 库开发环境的一个典型代码片段示例,用于说明如何处理常见的嵌入式任务: ```c #include "stm32g4xx_hal.h" // 初始化 ADC 配置函数 void MX_ADC_Init(void) { __HAL_RCC_ADC_CLK_ENABLE(); hadc.Instance = ADC1; hadc.Init.Resolution = ADC_RESOLUTION_12B; // 设置分辨率为 12 位 HAL_ADC_Init(&hadc); } int main(void) { HAL_Init(); // 系统初始化 MX_ADC_Init(); // 初始化 ADC while (1) { uint16_t adcValue = 0; HAL_ADC_Start(&hadc); // 启动 ADC 转换 if(HAL_OK == HAL_ADC_PollForConversion(&hadc, 10)) { // 等待转换完成 adcValue = HAL_ADC_GetValue(&hadc); // 获取转换后的数值 } // 处理 ADC 数据... } } ``` 此代码展示了 STM32 平台上的双路 AD 测量功能实现方法,类似于往届比中涉及的任务需求。 --- #### 注意事项 下载 PDF 文件前需确认资源合法性,避免侵犯版权或其他法律风险。同时注意验证文件的真实性和完整性,以免因错误版本影响学习效果。
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值