1.题目
NowCoder每天要给很多人发邮件。有一天他发现发错了邮件,把发给A的邮件发给了B,把发给B的邮件发给了A。于是他就思考,要给n个人发邮件,在每个人仅收到1封邮件的情况下,有多少种情况是所有人都收到了错误的邮件?即没有人收到属于自己的邮件
链接:https://www.nowcoder.com/questionTerminal/95e35e7f6ad34821bc2958e37c08918b
2.题目解析
- 前提:n个元素放到n个位置,元素和位置各不对应的方法用D(n)表示,那么D(n-1)表示n-1个元素放到n-1个位置
- 第一步:将位置k的元素放再第一个位置,那么就有n-1中方法
- 第二步:放置编号k的时候,有两种情况 ①将位置k的元素放在位置n,对于剩下的n-1个元素,由于第k个元素放到了位置n,剩下n-1个元素就有D(n-2)中方法 ② 第k个元素放到位置k,对于n-2个元素,就有D(n-1)中方法
- 综上得出:D(n) = (n-1)*(D[n-2] + D[i-1])
3.代码展示
#include <iostream>
#include <stdio.h>
using namespace std;
int main()
{
int n;
long long D[21] = {0,0,1};
// 对于0或1封邮件,发错的情况为0
int i;
for(i = 3; i < 21; ++i)
{
// 算出出错的次数,放在对应的位置
D[i] = (i-1)*(D[i-1] + D[i-2]);
}
while(scanf("%d", &n) != EOF)
{
cout << D[n] << endl;
}
return 0;
}