• 牛客网 PAT乙级(Basic Level)练习题 1023 考新郎


    题目描述

    过年期间,老家举行了一场盛大的集体婚礼,为了使婚礼进行的丰富一些,司仪临时想出了有一个有意思的节目,叫做“考新郎”,具体的操作是这样的:

    1. 首先,给每位新娘打扮得几乎一模一样,并盖上大大的红盖头随机坐成一排;
    2. 然后,让各位新郎寻找自己的新娘。每人只准找一个,并且不允许多人找一个;
    3. 最后,揭开盖头,如果找错了对象就要当众跪搓衣板...

    假设一共有n对新婚夫妇,其中有m个新郎找错了新娘,求发生这种情况一共有多少种可能。

    输入描述:

    输入包含多组数据。每组数据包含两个正整数n和m(2≤m≤n≤20)


    输出描述:

    对应每一组数据,输出一个正整数,表示n对新人中有m个新郎找错新娘的种数。

    输入例子:

    2 2
    3 2

    输出例子:

    1
    3
     意思就是说,先从n里选出m个,就是C(n,m),然后把这m个排序,前提是不能有任何一个是对应正确位置,也就是说不能有新郎选对了新娘,所有的应该排在错误的位置,这里就想到了容斥定理,总的排列是m!,然后得减去那些存在新郎选对新娘的,如果1个新郎一定选对了,其他的还有(m - 1)!种排法,且这些排法都不满足,而且这些排法中也存在其他m-1个新郎选对的情况,总的应该减去C(m,1)个(m - 1)!,但是这C(m,1)个当中仍然有重复的,还得加,任意两个都会有重复,重复的是(m - 2)!,所以加上C(m,2)个(m - 2)!,然后又是减,加。。
    代码:
    #include <iostream>
    #include <cstring>
    #include <cstdio>
    #include <algorithm>
    
    using namespace std;
    int n,m;
    long long fact[21];
    long long C(int a,int b) {
        long long aa = 1,bb = 1;
        for(int i = 0;i < b;i ++) {
            aa *= a - i;
            bb *= (i + 1);
        }
        return aa / bb;
    }
    int main() {
        fact[0] = 1;
        for(int i = 1;i <= 20;i ++) {
            fact[i] = fact[i - 1] * i;
        }
        while(~scanf("%d%d",&n,&m)) {
            long long e = fact[m],flag = -1;
            for(int i = 1;i <= m;i ++,flag *= -1) {
                e += fact[m - i] * C(m,i) * flag;
            }
            printf("%lld
    ",C(n,m) * e);
        }
    }
  • 相关阅读:
    [算法笔记] 扩展欧几里得算法
    [算法笔记] 数学基础
    [算法] 动态规划 (2)
    [算法笔记] 图论总结
    最简单的数据库入门教程—04—00—关系数据库
    最简单的数据库入门教程—03—数据库系统体系
    最简单的数据库入门教程—02—数据模型
    最简单的数据库入门教程—01—数据库系统概论
    最简单的数据库入门教程—00—数据库导论
    数据可视化分析
  • 原文地址:https://www.cnblogs.com/8023spz/p/9683877.html
Copyright © 2020-2023  润新知