SGU - 222 - Little Rooks (组合数)

来源:互联网 发布:instagram翻墙软件 编辑:程序博客网 时间:2024/05/29 16:45

222. Little Rooks

time limit per test: 0.25 sec.
memory limit per test: 65536 KB
input: standard
output: standard



Inspired by a "Little Bishops" problem, Petya now wants to solve problem for rooks. 

A rook is a piece used in the game of chess which is played on a board of square grids. A rook can only move horizontally and vertically from its current position and two rooks attack each other if one is on the path of the other. 

Given two numbers n and k, your job is to determine the number of ways one can put k rooks on an n × n chessboard so that no two of them are in attacking positions. 

Input

The input file contains two integers n (1 ≤ n ≤ 10) and k (0 ≤ k ≤ n2). 

Output

Print a line containing the total number of ways one can put the given number of rooks on a chessboard of the given size so that no two of them are in attacking positions. 

Sample test(s)

Input
4 4 
Output
24 
[submit]
[forum]

Author:Andrew StankevichResource:Little Chess Pieces Series, SPb IFMO 2003-2004 Authumn Training SessionsDate: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 longusing 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;} 












1 0