小明在得到很多巧克力之后,决定邀请朋友们分享。现在他共有 n 块巧克力,决定这样分配给朋友们:如果算上他自己共有 k 人,那么只要桌上至少有 k 块巧克力,每人就要拿走一块,逐轮进行,直到桌上的巧克力不足 k 块,剩下的都归小明。他还没想好要邀请几个朋友,不过至少要请 l 个人,至多请 r 个人,请帮小图灵算算,他最多能吃到多少块巧克力。
输入描述
一行,三个正整数 n,l,r(均不大于 100),分别代表巧克力总数和至少、至多可以邀请的朋友数量。
输出描述
一行,一个整数,表示小明最多能吃到的巧克力数量。
样例1
输入20 4 7
输出8
样例解释
如果共有 20 块巧克力,若邀请 4 人,算上小明共 5 人,每人直接拿走 4 块。
若邀请 5 人,共 6 人,每人拿走 3 块,小明再拿 2 块,共拿 5 块。
若邀请 6 人,共 7 人,每人拿走 2 块,小明再拿 6 块,共拿 8 块。
若邀请 7 人,共 8 人,每人拿走 2 块,小明再拿 4 块,共拿 6 块。
解题思路:
本题可以使用暴力枚举的方式来解决,枚举小明邀请的朋友数量,算出每次分配后小明能够得到的巧克力数目,最终取最大值即可。
具体来说,对于枚举到的朋友数量 $k$,分配后每人能得到 $\lfloor \frac{n}{k+1} \rfloor$ 块巧克力,小明能得到的巧克力数目就是 $n - (k+1) \times \lfloor \frac{n}{k+1} \rfloor$ 块,最后取所有结果中的最大值即为答案。
注意,这里分配巧克力时要求桌上至少有 $k$ 块巧克力,因此在计算每人能得到的巧克力数目时要除以 $k+1$ 而不是 $k$。
C++代码实现:
#include <iostream>
using namespace std;
int main() {
int n, l, r;
cin >> n >> l >> r;
int ans = 0;
for (int k = l; k <= r; k++) {
int rounds = n / k; // 总共可以进行的轮数
if (rounds == 0) { // 如果巧克力数不足k块,小明将全拿走
ans += n;
} else {
int left = n - rounds * k; // 每轮后剩余的巧克力数
int min_choco = rounds + (left >= k); // 每个人最少可以拿到的巧克力数
int max_choco = min_choco; // 每个人最多可以拿到的巧克力数
if (left > 0) { // 如果还有剩余巧克力,平均分配给每个人
max_choco++;
}
ans += min_choco * (k - 1) + max_choco - 1; // 小明可以拿到的巧克力数
}
}
cout << ans << endl;
return 0;
}
首先读入巧克力总数n以及至少和至多可以邀请的朋友数量l和r。
然后遍历l到r之间的每个数k,表示邀请的朋友数量为k-1。
如果巧克力数不足k块,小明将全拿走。
否则,计算总共可以进行的轮数rounds,以及每轮后剩余的巧克力数left。
对于每轮,除去小明,共有k-1个人需要分配巧克力。
如果left不足k块,那么每个人都可以拿到rounds块巧克力,小明可以拿到剩余的left块巧克力。
否则,每个人可以拿到rounds+1块巧克力,剩余的巧克力平均分配给每个人,小明可以拿到一块。
最终,将小明可以拿到的巧克力数累加到ans中,输出ans即可。
时间复杂度为O((r-l+1)n)。由于数据规模很小,可以通过本题。
答案出自c++ https://www.wodianping.com/
暴力枚举就行了
不知道你这个问题是否已经解决, 如果还没有解决的话: