CF397B题解
题意
一个人在凑钱,他只有面值从 $l$ 到 $r$ 的硬币,每种都有无限个。问是否可以凑出 $n$ 元钱。
思路
将题意转换为数学式子,能否找到一个数组 $a$,使得:
$$ \sum^x_{i=1}a_i(l\le a_i \le r)=n $$
其中 $x$ 代表数组 $a$ 的长度。
显然,我们可以很容易地推出 $x$ 的范围:
$$ \lceil \frac{n}{r}\rceil\le x \le \lfloor \frac{n}{l}\rfloor $$
(当 $a$ 的所有元素等于 $r$ 时,显然长度最小,等于 $l$ 时,显然长度最大)
那这有什么用呢?
这样我们就可以推出合法的 $n$ 的上下界!
若我们假设:
$$n=\lceil \frac{n}{r}\rceil\times l+k\le \lfloor \frac{n}{l}\rfloor \times r$$
变形为:
$$ n=(\frac{(k-\lceil \frac{n}{r}\rceil\times y)}{(l+y)}+\lceil \frac{n}{r}\rceil )\times (l+y)+(k-\lceil \frac{n}{r}\rceil\times y)\text{mod} (l+y) $$
(如果 $k$ 小于 $l$ 则加到某些元素上,多余则增加若干个元素)
其中 $(0\le y\le r-l)$。
所以,只要 $\lceil \frac{n}{r}\rceil\times l\le n \le \lfloor \frac{n}{l}\rfloor \times r$,则 $n$ 就一定可行。
代码
#include<bits/stdc++.h>
using namespace std;
long long t,n,l,r;
int main() {
cin>>t;
while(t--) {
scanf("%lld%lld%lld",&n,&l,&r);
n<=(n/l)*r&&n>=(n/r)*l?cout<<"Yes\n":cout<<"No\n";
}
}

浙公网安备 33010602011771号