链接 https://codeforces.com/contest/1538/problem/G
题意 有红色糖果 $x$ 个,蓝色糖果 $y$ 个。
可以将 $a$ 个红色糖果和 $b$ 个蓝色糖果或 $b$ 个红色糖果和 $a$ 个蓝色糖果打包成礼物。
求最多打包多少个礼物。
思路 设 $n$ 为最大礼物数量,显然礼物数量满足二分性。
若 $a=b$ ,$n=\lfloor\frac{min(x,y)}{a}\rfloor$。
否则,设 $a>b$,设第一种礼物数量为 $k$,那么第二种礼物数量为 $n-k$。
$ \begin{cases} ak+b(n-k)\le x \ a(n-k)+bk \le y \ n \ge 0 \end{cases} \longrightarrow \begin{cases} k \le \lfloor\frac{x-bn}{a-b}\rfloor \ k \ge \lceil\frac{y-an}{b-a}\rceil \ k \ge 0 \ k \le n \end{cases} $
若 $k$ 满足上述要求,则存在一种方式打包成 $n$ 个礼物,二分即可。
代码 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 #include <bits/stdc++.h> #define SZ(x) (int)(x).size() #define ALL(x) (x).begin(),(x).end() #define PB push_back #define EB emplace_back #define MP make_pair #define FI first #define SE second using namespace std;typedef double DB;typedef long double LD;typedef long long LL;typedef unsigned long long ULL;typedef pair<int ,int > PII;typedef vector<int > VI;typedef vector<PII> VPII;LL x,y,a,b; bool check (LL mid) { return max (0ll ,(LL)ceil (1.0 *(y-a*mid)/(b-a)))<=min (mid,(LL)floor (1.0 *(x-b*mid)/(a-b))); } int main () { ios::sync_with_stdio (false ); cin.tie (nullptr ); int T;cin>>T; while (T--) { cin>>x>>y>>a>>b; if (a==b) cout<<min (x,y)/a<<'\n' ; else { if (a<b) swap (a,b); LL l=0 ,r=1e9 ; while (l<r) { LL mid=l+r+1 >>1 ; if (check (mid)) l=mid; else r=mid-1 ; } cout<<l<<'\n' ; } } return 0 ; }