专栏文章
题解:P13013 [GESP202506 五级] 奖品兑换
P13013题解参与者 2已保存评论 1
文章操作
快速查看文章及其快照的属性,并进行相关操作。
- 当前评论
- 1 条
- 当前快照
- 1 份
- 快照标识符
- @miozxu3k
- 此快照首次捕获于
- 2025/12/03 03:54 3 个月前
- 此快照最后确认于
- 2025/12/03 03:54 3 个月前
非常不错的一道二分答案题目,整体不算太难。
思路如下:我们需要确定最多能兑换多少份奖品。兑换一份奖品可以使用两种方式:一种是使用 张课堂优秀券和 张作业优秀券,另一种是使用 张课堂优秀券和 张作业优秀券。
给出 张课堂优秀券和 张作业优秀券,我们需要找出最大的兑换份数 ,使得存在非负整数 和 ,其中 ,需要满足以下条件:
使用二分法来寻找最大的 。二分范围的下界为 ,上界为 ( 确保覆盖可能的解)。同时,检查函数中对于每个候选的 ,检查是否存在非负整数 满足:
根据 和 的大小关系,分情况处理:
- 当 和 相等时,只需验证 且 。
- 当 时,计算 的下界和上界,并检查是否存在整数 在 范围内。
- 当 时,同样计算 的下界和上界,并检查是否存在整数 在 范围内。
剩下就是二分答案的模板了,相信大家都可以看懂,上代码:
CPP#include <bits/stdc++.h>
using namespace std;
long long n, m, a, b;
bool check(long long t){
if((a + b) * t > n + m)
return false;
if(a == b){
if( a * t <= n && a * t <= m)
return true;
else
return false;
}
double low, high;
if(a > b){
low = (1.0 * a * t - m) / (a - b);
high = (1.0 * n - b * t) / (a - b);
}
else{
low = (1.0 * n - b * t) /(a - b);
high = (1.0 * a * t - m) /(a - b);
}
long long L = ceil(low);
long long R = floor(high);
L = max(L, (long long)0);
R = min(R, t);
return(L <= R);
}
int main(){
cin >> n >> m;
cin >> a >> b;
long long ans = 0;
long long left = 0;
long long right = max(n,m)/min(a,b) + 1;
while(left <= right){
long long mid =(left + right) / 2;
if(check(mid)){
ans = mid;
left = mid + 1;
}
else{
right = mid - 1;
}
}
cout << ans;
return 0;
}
相关推荐
评论
共 1 条评论,欢迎与作者交流。
正在加载评论...