NowCoder每天要给很多人发邮件。有一天他发现发错了邮件,把发给A的邮件发给了B,把发给B的邮件发给了A。于是他就思考,要给n个人发邮件,在每个人仅收到1封邮件的情况下,有多少种情况是所有人都收到了错误的邮件?
即没有人收到属于自己的邮件。
输入包含多组数据,每组数据包含一个正整数n(2≤n≤20)。
对应每一组数据,输出一个正整数,表示无人收到自己邮件的种数。
2<br/>3
1<br/>2
import java.util.*;
public class Main {
public static void main(String[] args){
Scanner scan = new Scanner(System.in);
long[] a = new long[22];
a[2] = 1;
a[3] = 2;
for (int i = 4; i < 22; i++){
a[i] = (i-1)*(a[i-1]+a[i-2]);
}
while (scan.hasNext()){
int n = scan.nextInt();
System.out.println(a[n]);
}
}
} import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
while (sc.hasNext()) {
int n = sc.nextInt();
System.out.println(count(n));
}
}
/**
* 错排算法,注意是long型
* @param n
* @return
*/
public static long count(int n) {
if (n == 1) {
return 0;
} else if (n == 2) {
return 1;
} else {
return (n - 1) * (count(n - 1) + count(n - 2));
}
}
}
有了递推公式,一切就迎刃而解了。
int main (void)
{
long long der[ 21 ] = { 0, 0, 1 };
int i;
for ( i = 3; i < 21; i++ ){
der[ i ] = ( i - 1 ) * ( der[ i - 2] + der[ i - 1 ] );
}
int n;
while ( scanf( "%d", &n ) != EOF ){
printf("%lld\n", der[ n ] );
}
return 0;
}