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";
}
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 使用C#创建一个MCP客户端
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列1:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现