P1909 [NOIP 2016 普及组] 买铅笔

记录33

#include <bits/stdc++.h>
using namespace std;
int f(int n,int m,int p){
	if(n%m==0) return n/m*p;
	else return (n/m+1)*p;
}
int main(){
	int n,a,b,c,a1,a2,b1,b2,c1,c2;
	cin>>n>>a1>>a2>>b1>>b2>>c1>>c2;
	a=f(n,a1,a2);
	b=f(n,b1,b2);
	c=f(n,c1,c2);
	int t=min(a,min(b,c));
	cout<<t;
  return 0;
}

题目传送门https://www.luogu.com.cn/problem/P1909


突破点

商店不允许将铅笔的包装拆开,因此 P 老师可能需要购买超过 n 支铅笔才够给小朋友们发礼物。👉打包思想

在商店每种包装的数量都足够的情况下,要买够至少 n 支铅笔最少需要花费多少钱。

👉求最小花费


思路

  1. 将三种包装需要的钱都求出来
  2. 进行比较后取出最小的方案

代码解析

#include <bits/stdc++.h>
using namespace std;
int f(int n,int m,int p){
	if(n%m==0) return n/m*p;
	else return (n/m+1)*p;
}
int main(){
	...
    ...
  return 0;
}

设置一个函数,传进来需要的参数,(需要数量,包装内铅笔的数量,价格)

最后返回花费的钱

if(n%m==0) return n/m*p;  如果数量刚好够,就直接算价钱

else return (n/m+1)*p;  如果不够就多买一份,然后算价钱

#include <bits/stdc++.h>
using namespace std;
int f(int n,int m,int p){
	if(n%m==0) return n/m*p;
	else return (n/m+1)*p;
}
int main(){
	int n,a,b,c,a1,a2,b1,b2,c1,c2;
	cin>>n>>a1>>a2>>b1>>b2>>c1>>c2;
	a=f(n,a1,a2);
	b=f(n,b1,b2);
	c=f(n,c1,c2);
	int t=min(a,min(b,c));
	cout<<t;
  return 0;
}

int t=min(a,min(b,c));  对三种包装进行价格比较,取出最小的价格


补充

在CSP-J算法竞赛中,模拟问题要求选手根据题目描述的规则或流程,通过编程实现对问题的模拟。这类问题考察选手对问题的理解能力、逻辑思维能力以及代码实现能力。以下是解决模拟问题的思路和技巧:

1. 仔细阅读题目

  • 理解问题描述:明确题目要求,理解每个操作的具体含义。

  • 确定输入输出格式:清楚输入数据的格式和输出结果的格式要求。

2. 分析问题步骤

  • 分解问题:将复杂问题分解为多个小步骤,逐步解决。

  • 确定模拟流程:明确每个步骤的操作对象和操作顺序。

3. 设计数据结构

  • 选择合适的数据结构:根据问题需求选择数组、链表、队列等数据结构。

  • 初始化数据:根据题目初始条件设置数据的初始状态。

4. 模拟操作

  • 逐步模拟:按照题目规则逐步模拟每个操作。

  • 状态更新:在模拟过程中及时更新数据结构中的状态。

5. 处理边界条件

  • 考虑特殊情况:如输入为空、极端值等。

  • 验证边界情况:确保代码在边界条件下也能正确运行。

6. 代码实现

  • 遵循编码规范:使用有意义的变量名,添加注释,提高代码可读性。

  • 逐步实现:先实现核心逻辑,再逐步完善细节。

7. 测试与验证

  • 测试样例:使用题目提供的样例输入验证代码的正确性。

  • 自定义测试用例:设计边界用例和特殊用例,检查代码的健壮性。

8. 优化代码

  • 时间优化:减少不必要的计算,采用更高效算法。

  • 空间优化:合理使用内存,避免内存溢出。

9. 调试技巧

  • 输出中间结果:在关键步骤输出变量值,检查逻辑是否正确。

  • 使用调试工具:利用调试器定位问题。

10. 总结与复盘

  • 总结经验:记录解题过程中遇到的问题和解决方法。

  • 复盘优化:思考是否有更好的解决方案或改进空间。

通过以上步骤,可以系统地解决模拟问题,确保代码的正确性和高效性。

<think>我们参考NOIP 2016普及组初赛试题中的铅笔问题。 问题描述:P老师需要购n支铅笔,商店有3种包装的铅笔,每种包装有不同的铅笔数量和价格。 P老师决定只同一种包装的铅笔(即只能选择一种包装,然后购若干包),目标是满足n支铅笔的需求,并且花费最小。 输入:第一行包含一个正整数n,表示需要的铅笔数量。接下来的三行,每行用两个正整数描述一种包装的铅笔: 第一个数表示这种包装内铅笔的数量,第二个数表示这种包装的价格。 输出:一个整数,表示P老师最少需要花费的钱。 思路: 1. 对于每种包装,我们需要计算为了至少到n支铅笔所需要的最小花费。 具体方法:用n除以每包的铅笔数量,如果不能整除,则需要多一包(向上取整)。 即:包数 = (n + 每包数量 - 1) / 每包数量 (整数除法,向上取整的技巧) 然后花费 = 包数 * 每包价格 2. 对三种包装分别计算花费,然后取最小值。 注意:由于n和每包数量都是正整数,我们可以使用整数除法向上取整的方法。 代码实现步骤: - 读入n - 循环3次,每次读入一种包装的铅笔数量(设为a)和价格(设为b) 计算需要购的包数:pack = (n % a == 0) ? (n / a) : (n / a + 1); 也可以使用:pack = (n + a - 1) / a; (这是整数向上取整的常用技巧) 然后计算总花费:cost = pack * b; - 比较三种包装的花费,输出最小值。 由于有三种包装,我们可以用一个数组来存储三种包装的花费,然后取最小值,也可以边读边比较。 下面我们用C语言实现: 示例输入: 57 2 2 50 30 30 27 示例输出: 54 解释:第一种包装每包2支铅笔,价格2元,需要29包(因为57/2=28.5,向上取整29),花费58元。 第二种包装每包50支,价格30元,需要2包(57/50=1.14,向上取整2),花费60元。 第三种包装每包30支,价格27元,需要2包(57/30=1.9,向上取整2),花费54元。 所以最小花费是54元。 注意:题目中给出的n最大可能为10000,铅笔数量和价格都是正整数(不超过10000),所以计算过程不会溢出。 代码: </think>以下是使用C语言解决NOIP 2016普及组"铅笔"问题的完整代码和详细思路: ### 问题分析 给定需要购铅笔总数 $n$ 和三种铅笔包装的信息(每包数量 $a_i$ 和价格 $b_i$)。目标:选择一种包装,通过购若干包使得总铅笔数 $\geq n$,并求最小花费[^1]。 **关键点**: 1. 只选择一种包装类型 2. 购数量需满足:$\text{购包数} \times a_i \geq n$ 3. 计算每种包装的最小花费:$\text{花费} = \lceil n / a_i \rceil \times b_i$ 4. 取三种包装花费的最小值 ### C语言代码实现 ```c #include <stdio.h> #include <limits.h> int main() { int n; scanf("%d", &n); // 读取需要购铅笔总数 int min_cost = INT_MAX; // 初始化最小花费为最大整数 // 处理三种包装 for (int i = 0; i < 3; i++) { int a, b; scanf("%d %d", &a, &b); // 读取当前包装的铅笔数量和价格 // 计算所需包数(向上取整) int packs = n / a; if (n % a != 0) packs++; // 如果不能整除,增加一包 // 计算当前包装总花费 int total_cost = packs * b; // 更新最小花费 if (total_cost < min_cost) { min_cost = total_cost; } } printf("%d\n", min_cost); // 输出最小花费 return 0; } ``` ### 代码解析 1. **输入处理**: - `n` 表示需要购铅笔总数 - 循环读取三种包装的铅笔数量 `a` 和价格 `b` 2. **包数计算**: - 使用整数除法 `n / a` 计算基础包数 - 通过 `if (n % a != 0) packs++` 实现向上取整 3. **花费计算**: - 当前包装总花费 = 包数 × 单价 (`packs * b`) - 使用 `min_cost` 记录全局最小花费 4. **时间复杂度**:$O(1)$,固定处理三种包装 ### 示例测试 **输入**: ``` 57 2 2 50 30 30 27 ``` **输出**: ``` 54 ``` **计算过程**: - 包装1:需 $\lceil 57/2 \rceil = 29$ 包 → $29 \times 2 = 58$ 元 - 包装2:需 $\lceil 57/50 \rceil = 2$ 包 → $2 \times 30 = 60$ 元 - 包装3:需 $\lceil 57/30 \rceil = 2$ 包 → $2 \times 27 = 54$ 元 - 最小花费为 54 元 ### 优化技巧 1. **避免除法取整**:可直接计算 `packs = (n + a - 1) / a` 2. **边界处理**:当 $n=0$ 时花费应为 $0$(题目隐含 $n \geq 1$) ### 典型应用场景 1. 资源采购优化(批量采购成本计算) 2. 活动物资筹备(最小化预算) 3. 算法竞赛中的贪心策略训练
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值