PAT乙级(Basic Level)练习题 考新郎

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

  1. 首先,给每位新娘打扮得几乎一模一样,并盖上大大的红盖头随机坐成一排;
  2. 然后,让各位新郎寻找自己的新娘。每人只准找一个,并且不允许多人找一个;
  3. 最后,揭开盖头,如果找错了对象就要当众跪搓衣板…
    假设一共有n对新婚夫妇,其中有m个新郎找错了新娘,求发生这种情况一共有多少种可能。

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

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

输入例子:

2 2
3 2

输出例子:

1
3

\color{blue}解题思路:
首先我们需要从n对夫妻中选出m对夫妻,总共有Cm,n=n!/m!/(n - m)!种情况。
接着这m对夫妻的新郎全部选错的情况f(m) = (m - 1) * (f(m - 1) * f(m - 2)),这个公式上前面好几道都推过,请参考我的博客 PAT乙级(Basic Level)练习题 发邮件
因此公式为:n!/m!/(n - m)! * f(m)
\color{blue}代码实现:

#include <iostream>
using namespace std;

int main() {
    int m = 0, n = 0;
    //fTable[n]记录n个人都悬错的情况种数,allTable[n]记录n的阶乘
    long long fTable[21] = {0, 0, 1}, allTable[21] = {1, 1, 2};
    for (int i = 3; i < 21; ++i) {
        //递推计算i个人全部拿错
        fTable[i] = (i - 1) * (fTable[i - 1] + fTable[i - 2]);
        //递推计算i的阶乘
        allTable[i] = i * allTable[i - 1];
    }
    //scanf返回值为正确输入数据的变量个数,当一个变量都没有成功获取数据时,此时返回-1
    while (scanf("%d %d", &n, &m) != - 1) {
        //组合公式Cm,n=n!/m!/(n - m)!,从n个中随机s选m个
        //从n对中选出m对,allTable[n] / allTable[m] /allTable[n - m]情况
        //选出的m对夫妻全部选错,fTable[m]种情况
        printf("%lld\n", allTable[n] / allTable[m] /allTable[n - m] * fTable[m]);
    }
    return 0;
}

在这里插入图片描述

发布了1005 篇原创文章 · 获赞 269 · 访问量 22万+

猜你喜欢

转载自blog.csdn.net/qq_41855420/article/details/104690822
今日推荐