Author: | Andrew Stankevich |
Resource: | Little Chess Pieces Series, SPb IFMO 2003-2004 Authumn Training Sessions |
Date: | 2003-10-01 |
思路:因为是象棋中的车,它可以攻击同一行和同一列的棋子,所以不妨将每个车固定在一列中,这样不会影响到结果(自己想想为什么)
①先考虑n == k的情况
比如n = 3, k = 3
这时有三个车,且棋盘为3行3列,把第i车固定到第i列上,可以得到the numbers of ways,即3*2*1,
可以推广到n*(n-1)*(n-2)*.....*1 (k = n)
②而n > k时,先把棋盘看做n*k网格(n行k列,k个车放到k列上)的,有ans = n*(n-1)*......*(n - k + 1)
再把这个棋盘扩展为n*n网格的,可以发现只是将列数增加到了n而已
现在我们可以从n列中取出k列分给k个数,即组合数C(n, k);
由乘法原理,于是可以得出答案为n*(n-1)*......*(n - k + 1)*C(n, k);(此时对①情况也适用)
③当n < k时输出0
AC代码:
#include <cstdio> #include <cstring> #include <iostream> #include <algorithm> #define LL long long using namespace std; LL ans; int main() { int n, k; while(scanf("%d %d", &n, &k) != EOF) { if(k > n) { printf("0\n"); } else if(k == 0) { printf("1\n"); } else { ans = 1; for(int i = n; i > n - k; i--) { ans *= i; } ans = ans * ans; for(int i = k; i > 1; i--) { ans /= i; } cout << ans << endl; } } return 0; }