Fork me on GitHub

SCAU 8635 气球

8635 气球

时间限制:500MS  内存限制:1000K 提交次数:0 通过次数:0

题型: 编程题   语言: 无限制

Description

    一天,OYY 从外面打完比赛回来,手上拿了很多个气球,颜色各不相同。他见到我,就说,你看,我拿了很多气球!
我膜拜死了!!然后他就问了我一个问题,如果把这里的气球分成若干份。有多少种分法呢?
    由于我数学非常菜,顿时头晕了,因此希望大家能帮我解答这个问题(@_@))

Input

输入数据有2行
第1 行有两个数n,m,分别代表oyy 手上的气球个数和分的份数(n<=10,m<=5)
第2 行有m 个数,分别代表每一份的个数,保证总个数等于n

Output

输出数据有1行,输出一个数代表不同分法的总数。

Sample Input

3 1
3

Sample Output

1

Hint

Sample Input2:
4 2
2 2
Sample Output2:
3

Source

Ick2

Provider

admin

 

复制代码
#include<stdio.h>
#include<string.h>
int option1(int m, int times)
{
    int i, res = m;
    while(--times)
    res *= (--m);
    return res;
}
 
//函数option1和option2主要计算Cm取n,在option1中有m*(m-1)*.....*(m-times+1)
//option2函数计算n!

int option2(int n)
{
    if(n == 1 || n == 2) return n;
    else return n*option2(n-1);
}

int main()
{
    int n, m,  depart[11], i, j, temp, count, mis, res;
    memset(depart, 0, sizeof(depart));
    scanf("%d%d", &n, &m);
    for(i=0; i<m; ++i)
    {
        scanf("%d", &temp);
        depart[temp]++;
    }
    res = count = mis = 1;
    for(i=1; i<=10; ++i)
    {
        count = mis = 1;
        if(depart[i] !=0)
        {
            temp = depart[i];
            while(temp--)
            {
                count  *= (option1(n, i)/option2(i));
                n -= i;
            }
            res =res * count/(option2(depart[i])) ;
        }
    }
    printf("%d\n", res);

    return 0;
}
复制代码


解题报告:

看到这题目,虽然有种熟悉的感觉,但更多的还是害怕,因为对于排列组合的知识差不多都忘光了。

本题主要处理分堆后,堆中的气球数量相同的情况,这时变成了组合的问题而不需要排序,处理的办法是先将此看为排序,然后只取排序中的一种情况即可,而只取一种的

操作方法是除以相同数目堆的堆数的阶乘。

 

posted @   Gifur  阅读(414)  评论(0编辑  收藏  举报
编辑推荐:
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
阅读排行:
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 分享 3 个 .NET 开源的文件压缩处理库,助力快速实现文件压缩解压功能!
· Ollama——大语言模型本地部署的极速利器
· DeepSeek如何颠覆传统软件测试?测试工程师会被淘汰吗?
TOP
点击右上角即可分享
微信分享提示