Sicily 1950. Brain Teasers

来源:互联网 发布:淘宝宣传软文 编辑:程序博客网 时间:2024/06/03 17:03

1950. Brain Teasers

Constraints

Time Limit: 1 secs, Memory Limit: 32 MB

Description

Alice and Bob love playing brain teasers with each other. One day, they decided to play brain teasers again. Then Alice asked Bob:

“I have n different boxes and n different keys, each key can only open one unique box. Now all the keys are put into the n boxes and each box contains exactly one key. I will tell you which box contains which key, and which key can open which box, and you are allowed to open some boxes by violence. Then can you tell me what the minimum number of boxes that should be opened by violence is, so that you’re able to open every box?”

And Bob answered:

“Good question, but obviously it’s not hard for me. I can solve it in this way….”   Then Alice said:

“Hmm, yes, it’s not hard enough. So let me make some modifications: let’s call it an n-key permutation to make each of the n boxes contain exactly one key. And you are only allowed to open at most k boxes by violence. Then how many n-key permutations are there, so that after I tell you the information about the key permutation and the correspondence between keys and boxes, you are able to open all the boxes?”

   “For example, suppose n=3, k=1, and we number the keys and the boxes from 1 to n respectively, so that key i can open box i, then permutation (2,3,1) denotes that box1 contains key2, box2 contains key3, and box3 contains key1. As you are allowed to open 1 box by violence, you can open box1 by violence, get key2, and open box2, get key3, and finally open box3. So under key permutation (2, 3, 1) you are able to open all the boxes with at most one chance of using violence. What’s more, only permutation (3, 1, 2) is also satisfiable, so when n=3, k=1, only under 2 different permutations, you are able to open all the boxes.”

“Well, this problem is indeed not so easy. Maybe I should ask somebody to help me”. Bob said. So he decided to turn to you, his good friend and a computer expert, to help him find out the answer. Could you help him please?

Input

Input may contain multiple test cases. For each test case, there is one line, containing two integers, n and k, (1<=n<=100, 0<=k<=n). Input is terminated by a line containing two 0s, which should not be processed.

Output

For each test case, just output the number of different permutations satisfying the requirement. Each test case should correspond to one line. No more blank is allowed.

Sample Input

3 10 0

Sample Output

2

// Problem#: 1950// Submission#: 3591867// 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 <algorithm>#include <string.h>using namespace std;const int MAXN = 100;class BigInteger {    static const int MAXN_LEN = 200;    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]);    }};int n, k;BigInteger f[MAXN + 1][MAXN + 1];void preprocess() {    f[0][0] = 1;    for (int i = 1; i <= MAXN; i++)        for (int j = 1; j <= MAXN; j++)             f[i][j] = f[i - 1][j - 1] + f[i - 1][j] * (i - 1);}bool input() {    scanf("%d%d", &n, &k);    return n || k;}int main() {    preprocess();    while (input()) {        BigInteger ans(0);        for (int i = 1; i <= k; i++) ans = ans + f[n][i];        ans.print();        puts("");    }    return 0;}                                 


0 0
原创粉丝点击