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;
}