当前位置: 首页 > news >正文

[GESP202506 五级] 奖品兑换

题目描述

班主任给上课专心听讲、认真完成作业的同学们分别发放了若干张课堂优秀券和作业优秀券。同学们可以使用这两种券找班主任兑换奖品。具体来说,可以使用 aaa 张课堂优秀券和 bbb 张作业优秀券兑换一份奖品,或者使用 bbb 张课堂优秀券和 aaa 张作业优秀券兑换一份奖品。

现在小 A 有 nnn 张课堂优秀券和 mmm 张作业优秀券,他最多能兑换多少份奖品呢?

输入格式

第一行,两个正整数 n,mn,mn,m,分别表示小 A 持有的课堂优秀券和作业优秀券的数量。

第二行,两个正整数 a,ba,ba,b,表示兑换一份奖品所需的两种券的数量。

输出格式

输出共一行,一个整数,表示最多能兑换的奖品份数。

输入输出样例 #1

输入 #1

8 8
2 1

输出 #1

5

输入输出样例 #2

输入 #2

314159 2653589
27 1828

输出 #2

1599

说明/提示

对于 60%60\%60% 的测试点,保证 1≤a,b≤1001 \le a,b \le 1001a,b1001≤n,m≤5001 \le n,m \le 5001n,m500

对于所有测试点,保证 1≤a,b≤1041 \le a,b \le 10^41a,b1041≤n,m≤1091 \le n,m \le 10^91n,m109

提交链接

奖品兑换

思路分析

对于 60%60\%60% 的测试点的思路:

🧠 解题思路:暴力枚举。

  1. 枚举兑换 (a, b) 型奖品的次数为 iii

  2. 枚举兑换 (b, a) 型奖品的次数为 jjj

  3. 判断是否能用现有的 nnn 张课堂券和 mmm 张作业券完成这 i+ji + ji+j 次兑换;

  4. 如果能,则更新当前最大兑换份数 cnt = max(cnt, i + j)

  5. 最终输出最大值 cntcntcnt

🔍 枚举逻辑解释

每一次枚举 (i, j),对应尝试使用 iii 次第一种组合和 jjj 次第二种组合;

  • 计算总共需要多少课堂券:i * a + j * b

  • 计算总共需要多少作业券:i * b + j * a

如果二者都不超过所拥有的 nnnmmm,就认为当前方案可行

枚举完所有可能的 iii, jjj 组合,取最大合法值

⏱ 时间与空间复杂度

时间复杂度:O(L2)O(L^2)O(L2),其中 LLL 是枚举上限(60%60\%60% 的数据 nnnmmm 最大为 500500500),满足时间复杂度的要求。

参考代码

#include <bits/stdc++.h>
using namespace std;int main()
{int n, m, a, b;cin >> n >> m; // 小 A 持有的课堂优秀券和作业优秀券的数量。cin >> a >> b; // 兑换一份奖品所需的两种券的数量int cnt = 0;for (int i = 0; i <= 500; i++) // 枚举(a,b)兑换的次数{for (int j = 0; j <= 500; j++) // 枚举(b,a)兑换的次数{int n1 = i * a + j * b, m1 = i * b + j * a;if (n1 <= n && m1 <= m){cnt = max(cnt, i + j);}}}cout << cnt;return 0;
}

对于 100%100\%100% 的测试点的思路:

🧠 解题思路

本题本质是一个混合资源分配最大化问题,目标是确定最大可兑换份数 xxx,在满足:

  1. 消耗的课堂券总数 ≤n≤ nn

  2. 消耗的作业券总数 ≤m≤ mm

但由于每份奖品可用两种不同方式兑换,直接贪心或模拟不易确定是否可行。因此我们使用:

✅ 二分答案 + 可行性判定

  1. 步骤一:二分最大可兑换份数 xxx

    • 初始范围为 [0, 1e9]

    • 每次尝试中间值 midmidmid,判断是否存在一种组合方式能兑换 midmidmid 份奖品

  2. 步骤二:判定某个兑换数量 xxx 是否可行(check 函数)

    • 假设使用 iii 份方案 111(类型 (a,b)

    • 则剩下的 x−ix - ixi 份使用方案 222(类型 (b,a)

    总消耗:

    • 课堂券 = i * a + (x - i) * b

    • 作业券 = i * b + (x - i) * a

    • 枚举 iii 的可能值(000xxx),判断是否存在满足券数限制的某个 iii

    • 由于 xxx 很大,枚举 iii 可能较慢,所以我们在 check 函数中也使用二分枚举 iii

if(n < m) swap(n , m);
if(a < b) swap(a , b);
  • 把较大的券数放在 nnn,较大的需求放在 aaa
  • 多的换多的,少的换少的,符合逻辑。
long long l = 0, r = 1e9, mid, ans;
while (l <= r)
{mid = l + (r - l) / 2;if (check(mid)){ans = mid;l = mid + 1;}else{r = mid - 1;}
}
cout << ans;
  • 对奖品总数进行二分
  • 奖品越多,需要的券越多,满足单调性
bool check(int x)
{// 总的奖品数量为x 如何分成 (a , b) + (b , a)long long left = 0, right = x, Mid; // 二分(a , b)的数量while (left <= right){Mid = left + (right - left) / 2;long long n1 = Mid * a + (x - Mid) * b, m1 = Mid * b + (x - Mid) * a;if (n1 <= n && m1 <= m){return true;}else if (n1 > n){right = Mid - 1;}else{left = Mid + 1;}}return false;
}
  • 总的奖品数量为 xxx,二分 (a,b) 组合的使用数量。
  • 对应的课堂券和作业券这两项都不超过 nnnmmm
  • 若课堂券超过 nnn,修改 right = Mid - 1,若作业券超过 mmm,修改 left = Mid + 1
  • 使用更多的 (a,b) 组合,对 (n,m) 消耗更多,满足单调性。

参考代码

#include <bits/stdc++.h>
using namespace std;long long n, m, a, b;
bool check(int x)
{//总的奖品数量为x 如何分成 (a , b) + (b , a)long long left = 0 , right = x , Mid;   //二分(a , b)的数量while(left <= right){Mid = left + (right - left) / 2;long long n1 = Mid * a + (x - Mid) * b , m1 = Mid * b + (x - Mid) * a;if(n1 <= n && m1 <= m){return true;}else if(n1 > n){right = Mid - 1;}else{left = Mid + 1;}}return false;}
int main()
{cin >> n >> m; // 小 A 持有的课堂优秀券和作业优秀券的数量。cin >> a >> b; // 兑换一份奖品需要a张课堂优秀券 + b张作业优秀券  或者 b张课堂优秀券 + a张作业优秀券//多的兑换多的 少的兑换少的if(n < m) swap(n , m);if(a < b) swap(a , b);// 枚举枚举总的奖品数量long long l = 0, r = 1e9, mid , ans;while (l <= r){mid = l + (r - l) / 2;if(check(mid)){ans = mid;l = mid + 1;}else{r = mid - 1;}}cout << ans;return 0;
}
http://www.lryc.cn/news/606253.html

相关文章:

  • Python列表完全指南:从基础到实战(2025版)
  • 八股训练--Spring
  • C#反射的概念与实战
  • 网络编程-IP
  • TCP窗口缩放配置在云服务器高延迟网络中的参数调整测试
  • Android端RTMP低延迟播放器在工业与智能场景下的架构与落地
  • 抓大鹅小游戏微信抖音流量主小程序开源
  • TGD第九篇:三维应用——视频边缘检测
  • 【AI论文】MUR:面向大型语言模型的动量不确定性引导推理
  • cuda编程笔记(11)--学习cuBLAS的简单使用
  • Coze Studio概览(四)--Prompt 管理功能详细分析
  • 分布式锁的基本原理和基于lua脚本的实现(Redisson)
  • 红黑树×协程×内存序:2025 C++后端核心三体问题攻防手册
  • 旅游城市数量最大化 01背包问题
  • 如何解决pip安装报错ModuleNotFoundError: No module named ‘plotly’问题
  • Mac安装Navicat教程Navicat Premium for Mac v17.1.9 Mac安装navicat【亲测】
  • IK 字段级别词典的升级之路
  • 【RH134 问答题】第 11 章 管理网络安全
  • ACL 2024 大模型方向优秀论文:洞察NLP前沿​关键突破!
  • 前端框架Vue3(四)——组件通信及其他API
  • SecurityContextHolder 管理安全上下文的核心组件详解
  • python之使用ffmpeg下载直播推流视频rtmp、m3u8协议实时获取时间进度
  • 金融分类提示词演示
  • 代码随想录Day35:动态规划(背包问题 二维 一维、分割等和子集)
  • 守护金融核心业务 | 博睿数据《金融业务全景与全链路智能可观测体系建设白皮书》发布!
  • 云上服务器常见的存储方式和类型
  • MySQL 中的 JOIN 操作有哪些类型?它们之间有什么区别?
  • vk框架或者普通函数封装的一些函数可以拿取使用【会持续更新】
  • Maven模块化开发与设计笔记
  • 一起学springAI系列一:初体验