题解 | #放苹果#

放苹果

https://www.nowcoder.com/practice/bfd8234bb5e84be0b493656e390bdebf

#include <iostream>
using namespace std;

//统计m个相同的苹果放入n个相同的盘子中有多少种放法,其中o为每个盘子可放的最多苹果个数
int counts(const int m, const int n, const int o) {
    //若苹果数为0,则只有一种放法
    if (m == 0)
        return 1;
    //若盘子数为0,但苹果数不为0,则没有放法或前几个盘子的放法不成立
    if (n == 0)
        return 0;
    //若只有一个苹果,则无论放到哪个盘子都是一样的,只有一种放法
    if (m == 1)
        return 1;
    //若只有一个盘子,则苹果都只能放到这个盘子里,只有一种放法
    if (n == 1)
        return 1;
    //假设往第一个盘子里放i个苹果,为方便计算,令i从大到小开始统计
    //第一个盘子里的苹果个数不能超过苹果总数,也不能超过单个盘子里的最大苹果数,所以取i的最大值为m和o的较小者
    int i = m < o ? m : o;
    //如果盘子的个数超过苹果的个数,由于单个苹果不能拆分,有n-m个盘子一直是空的,统计前m个盘子的放法即可
    if (m < n)
        return counts(m, m, i);
    //用于记录放法的个数,便于累加
    int count = 0;
    do {
        //递归求出第一个盘子放了i个苹果的放法
        count += counts(m - i, n - 1, i);
        i--;
        //将苹果平均分给每个盘子时每个盘子有m/n个苹果,若第一个盘子里所放苹果少于平均值,则必有盘子里的苹果多于平均值,会与之前统计过的放法重复
        //由于m/n不总是整数,将运算数转化为浮点类型确保结果准确
    } while (i >= (float)m / n);
    return count;
}

int main() {
    int m, n;
    while (cin >> m >> n) { // 注意 while 处理多个 case
        cout << counts(m, n, m) << endl;
    }
}
// 64 位输出请用 printf("%lld")

全部评论

相关推荐

点赞 评论 收藏
分享
梦倩倩:同学,瞅瞅我司,医疗独角兽,校招刚开,名额有限,先到先得,****最新动态,绿灯直达,免笔试~
我的秋招日记
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务