UVA10338 Mischievous Children【组合数学】

Adam’s parents put up a sign that says “CONGRATULATIONS”. The sign is so big that exactly one letter fits on each panel. Some of Adam’s younger cousins got bored during the reception and decided to rearrange the panels. How many unique ways can the panels be arranged (counting the original arrangement)?
Input
The first line of input is a single non-negative integer. It indicates the number of data sets to follow. Its value will be less than 30001.
    Each data set consists of a single word, in all capital letters.
    Each word will have at most 20 letters. There will be no spaces or other punctuation.
    The number of arrangements will always be able to fit into an unsigned long int. Note that 12! is the largest factorial that can fit into an unsigned long int.
Output
For each word, output the number of unique ways that the letters can be rearranged (counting the original arrangement). Use the format shown in Sample Output, below.
Sample Input
3
HAPPY
WEDDING
ADAM
Sample Output
Data set 1: 60
Data set 2: 2520
Data set 3: 12

问题链接:UVA10338 Mischievous Children
问题简述:给定字符串,计算其字母重排的数量(不同单词的数量)。
问题分析:先根据字母数量算出全排列,然后去除同一字母的重复排列。
程序说明:(略)
参考链接:(略)
题记:(略)

AC的C++语言程序如下:

/* UVA10338 Mischievous Children */

#include 

using namespace std;

typedef long long LL;
const int N = 20 + 1;
char s[N];
int cnt[26];

LL fact(int n)
{
    long long ret = 1LL;
    for (int i = 2 ; i <= n ; i++)
        ret *= i;
    return ret;
}

int main()
{
    int n;
    scanf("%d", &n);
    for(int k = 1; k <= n; k++) {
        scanf("%s", s);

        memset(cnt, 0, sizeof(cnt));
        LL ans = fact(strlen(s));
        for(int i = 0; s[i]; i++)
            cnt[s[i] - 'A']++;
        for(int i = 0; i < 26; i++)
            if(cnt[i]) ans /= fact(cnt[i]);

        printf("Data set %d: %lld\n", k, ans);
    }

    return 0;
}

你可能感兴趣的:(#,ICPC-组合数学,#,ICPC-UVA)