欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

【发邮件】C++

程序员文章站 2022-05-14 18:16:07
...

题目描述:

NowCoder每天要给很多人发邮件。有一天他发现发错了邮件,把发给A的邮件发给了B,把发给B的邮件发给了A。于是他就思考,要给n个人发邮件,在每个人仅收到1封邮件的情况下,有多少种情况是所有人都收到了错误的邮件?
即没有人收到属于自己的邮件。

输入描述:

输入包含多组数据,每组数据包含一个正整数n(2≤n≤20)

输出描述:

对应每一组数据,输出一个正整数,表示无人收到自己邮件的种数

解题思路:

要解决这个问题首先我们先来了解一个小故事:
某人给五个朋友写信,邀请他们来家中聚会。请柬和信封交由助手去处理。粗心的助手却把请柬全装错了信封。请问:助手会有多少种装错的可能呢?
解决方法:
瑞士著名数学家欧拉按一般情况给出了一个递推公式:
用A、B、C……表示写着n位友人名字的信封,a、b、c……表示n份相应的写好的信纸。把错装的总数为记作D(n)。假设把a错装进B里了,包含着这个错误的一切错装法分两类:
(1)b装入A里,这时每种错装的其余部分都与A、B、a、b无关,应有D(n-2)种错装法。    
(2)b装入A、B之外的一个信封,这时的装信工作实际是把(除a之外的)n-1份信纸b、c……装入(除B以外的)n-1个信封A、C……,显然这时装错的方法有D(n-1)种。
总之在a装入B的错误之下,共有错装法D(n-2)+D(n-1)种。
a装入C,装入D……的n-2种错误之下,同样都有D(n-1)+D(n-2)种错装法,因此D(n)=(n-1)[D(n-1)+D(n-2)]

代码:

#include<iostream>
#include<vector>
using namespace std;

int main()
{
	int n;
	while (cin >> n)
	{
		vector<long long>temp(n+2);
		temp[0] = 0;
		temp[1] = 0;
		temp[2] = 1;
		for (int i = 3; i <= n; i++)
		{
			temp[i] = (i - 1)*(temp[i - 2] + temp[i - 1]);
		}
		cout << temp[n] << endl;
	}
	system("pause");
	return 0;
}

解题思路参照:
https://blog.csdn.net/a1097304791/article/details/84197731

相关标签: 日常练习