SGU[222] Little Rooks
Description
描述
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.
受到“Little BIshops”问题的启发,Petya现在想要解决关于车的问题。
车是方形网格棋盘上的一枚棋子。它只能横向或者纵向移动,如果有别的车在它的路线上,那么它们可以相互攻击。
给定两个数字n和k,你的任务是求在n × n的棋盘上放置k个车,使得他们不相互攻击的方案数。
Input
输入
The input file contains two integers n (1 ≤ n ≤ 10) and k (0 ≤ k ≤ n^2).
输入包含两个整数n (1 <= n <= 10)和k (0 <= k <= n^2)。
Output
输出
Write index I for given number as the first number in line. Write I super-primes numbers that are items in optimal presentation for given number. Write these I numbers in order of non-increasing.
第一行输出指定的索引I。第二行输出I个符合条件的一个超级素数的组合。将这I个数按非增排序。
Sample Input
样例输入
6
Sample Output
样例输出
2
3 3
Analysis
分析
由于K个车每行只能放一个,所以一共有K!种情况,一共有N * N的棋盘,行列选择共C(N, K) * C(N, K)种情况。
因此,通过排列组合,我们有 ans = C(N, K) * C(N, K) * K!。
化简可得ans = N! / K! / (N - K)! * N! / (N - K)!。
Solution
解决方案
#include <iostream> #include <algorithm> using namespace std; const int MAX = 16; unsigned long long f[MAX]; int main() { f[0] = 1; for(int i = 1; i < MAX; i++) { f[i] = f[i - 1] * i; } int N, K; while(cin >> N >> K) { if(K > N) { cout << 0 << endl; } else { cout << f[N] / f[K] / f[N - K] * f[N] / f[N - K] << endl; } } return 0; }
还以为类似八皇后,准备写Check函数,后来发现只是简单的排列组合而已。