时间限制400ms
内存限制512.00M
难度普及/提高−
历史分数100
提交记录 查看题解 题目反馈
标签
GESP
题目背景
为了保证只有时间复杂度正确的代码能够通过本题,时限下降为 400 毫秒。
题目描述
班主任给上课专心听讲、认真完成作业的同学们分别发放了若干张课堂优秀券和作业优秀券。同学们可以使用这两种券找班主任兑换奖品。具体来说,可以使用 a 张课堂优秀券和 b 张作业优秀券兑换一份奖品,或者使用 b 张课堂优秀券和 a 张作业优秀券兑换一份奖品。
现在小 A 有 n 张课堂优秀券和 m 张作业优秀券,他最多能兑换多少份奖品呢?
输入格式
第一行,两个正整数 n,m,分别表示小 A 持有的课堂优秀券和作业优秀券的数量。
第二行,两个正整数 a,b,表示兑换一份奖品所需的两种券的数量。
输出格式
输出共一行,一个整数,表示最多能兑换的奖品份数。
输入输出样例
输入 #1复制
8 8 2 1
输出 #1复制
5
输入 #2复制
314159 2653589 27 1828
输出 #2复制
1599
说明/提示
对于 60% 的测试点,保证 1≤a,b≤100,1≤n,m≤500。
对于所有测试点,保证 1≤a,b≤104,1≤n,m≤109。
第一种做法暴力(得80分):
#include <bits/stdc++.h> using namespace std; #define int long long const int P=1e9+7; const int N=1e5+10; int n,m,a,b,ans; signed main(){ ios::sync_with_stdio(false); cin.tie(0); cout.tie(0); cin>>n>>m; cin>>a>>b; if(a<b) swap(a,b);//确保 a 较大 while(n>=a || m>=a){ if(n<m)swap(n,m); if(m<b)break; n-=a; m-=b; ans++;//从n,m中选择较大的变量减去较大的花费 } cout<<ans<<endl; return 0; }第二种做法AC代码:
#include <bits/stdc++.h> #define int long long using namespace std; const int P=1e9+7; const int N=1e5+10; int n,m,a,b,ans; int s,d; signed main(){ cin>>n>>m; cin>>a>>b; if(a<b)swap(a,b); if(a==b){//进行特判 cout<<min(n,m)/a<<endl; return 0; } s=a+b,d=a-b; while(n>=a||m>=a){ if(n<m)swap(n,m); int x=(n-m)/d; if(x==0){//当n-m<d时 int y=m/s; ans+=y*2; n-=y*s,m-=y*s; x=2; } int v=min(n/a,min(m/b,x)); ans+=v,n-=v*a,m-=v*b; if(m<b) break;//不可进行兑换 } cout<<ans<<endl; return 0; }