2679. Rooks
Constraints
Time Limit: 1 secs, Memory Limit: 256 MB
Description
Many mathematical problems on chessboard have been studied. The 8-queens problem, may be the most famous, is to place 8 queens on the chessboard so that they do not attack each other. This problem is probably as old as the chess game itself, and thus its origin is not known, but it is known that Gauss studied this problem.
The same sort of question about rooks can be asked. Two rooks are said to be attacking each other if they are placed in the same row or column of the chessboard. How many ways are there to place 8 non-attacking rooks on a chessboard? The answer is quit easy, and can be soled generally: on an n by n chessboard, the number of ways to place n non-attacking rooks is n! (The two ways of placing on 2-by-2 chessboard are shown in Figure 6.1.1.
R
|
|
|
|
R
|
|
R
|
|
R
|
|
Figure 6.1.1
two ways of placing on 2-by-2 chessboard
Since a n-by-n chessboard can also be considered to be a n+1 by n+1 grid, a path can be drawn along the grid line from the upper left corner to the lower right corner by going right or down at each turning.
A configuration of a chessboard is a placing of rooks with a path that all rooks are below the path (all three configurations of 2-by-2 chessboard are shown in Figure6.1.2).
R
|
|
|
R
|
|
|
|
R
|
|
R
|
|
|
R
|
|
R
|
|
Figure 6.1.2 all configurations of 2-by-2 chessboard
Your task is to write a program to calculate the number of configurations in n-by-n chessboard.
Input
The input is a sequence of positive integers each in a separate line. The integers are between 1 and 100, inclusive, indicating the size of the chessboard. The end of the input is indicated by a zero.
Output
The output should be composed of lines each corresponding to an input line except the last zero. An output line includes the number of configurations of the chessboard with the input size. No other characters should be inserted in the output.
Sample Input
2 0
Sample Output
3
Problem Source
系列热身赛5@2011年上半学期算法考试和4+2选拔赛
// Problem#: 2679
// Submission#: 3592109
// The source code is licensed under Creative Commons Attribution-NonCommercial-ShareAlike 3.0 Unported License
// URI: http://creativecommons.org/licenses/by-nc-sa/3.0/
// All Copyright reserved by Informatic Lab of Sun Yat-sen University
#include <stdio.h>
#include <string.h>
#include <algorithm>
using namespace std;
class BigInteger {
static const int MAXN_LEN = 2000;
int d[MAXN_LEN];
int len;
public:
BigInteger(int v = 0) {
memset(d, 0, sizeof(d));
len = 0;
while (v > 0) {
d[len++] = v % 10;
v /= 10;
}
if (len == 0) len = 1;
}
BigInteger operator + (const BigInteger other) const {
BigInteger ret;
ret.len = max(len, other.len);
for (int i = 0; i < ret.len; i++) ret.d[i] = d[i] + other.d[i];
for (int i = 0; i < ret.len; i++) {
if (ret.d[i] > 9) {
ret.d[i] -= 10;
ret.d[i + 1]++;
}
}
if (ret.d[ret.len] > 0) ret.len++;
return ret;
}
BigInteger operator * (const BigInteger other) const {
BigInteger ret;
ret.len = len + other.len - 1;
for (int i = 0; i < len; i++)
for (int j = 0; j < other.len; j++) ret.d[i + j] += d[i] * other.d[j];
for (int i = 0; i < ret.len; i++)
if (ret.d[i] > 9) {
ret.d[i + 1] += ret.d[i] / 10;
ret.d[i] %= 10;
}
if (ret.d[ret.len] > 0) ret.len++;
while (ret.len > 1 && ret.d[ret.len - 1] == 0) ret.len--;
return ret;
}
void print() {
for (int i = len - 1; i >= 0; i--) printf("%d", d[i]);
printf("\n");
}
};
BigInteger ans[110], dp[110][110];
BigInteger sum;
int main() {
int i, j;
dp[1][0] = 1;
ans[1] = 1;
for (i = 2; i <= 100; i++) {
sum = 0;
for (j = 0; j < i; j++) {
sum = sum + dp[i - 1][j];
dp[i][j] = sum * (i - j);
ans[i] = ans[i] + dp[i][j];
}
}
int n;
while (scanf("%d", &n) && n) ans[n].print();
return 0;
}