222. Little Rooks
time limit per test: 0.25 sec.
memory limit per test: 65536 KB
memory limit per test: 65536 KB
input: standard
output: 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.
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 ≤ n 2).
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
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;
}