字串数
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 1430 Accepted Submission(s): 257
Problem Description
一个A和两个B一共可以组成三种字符串:"ABB","BAB","BBA".
给定若干字母和它们相应的个数,计算一共可以组成多少个不同的字符串.
给定若干字母和它们相应的个数,计算一共可以组成多少个不同的字符串.
Input
每组测试数据分两行,第一行为n(1<=n<=26),表示不同字母的个数,第二行为n个数A1,A2,...,An(1<=Ai<=12),表示每种字母的个数.测试数据以n=0为结束.
Output
对于每一组测试数据,输出一个m,表示一共有多少种字符串.
Sample Input
2 1 2 3 2 2 2 0
Sample Output
3 90
Source
Recommend
JGShining
(a1+a2+ ... +an)! / a1! / a2! / ... / an!
主要还是写高精度!
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <cassert>
#define LEN 1500
void Sub (int *, int *);
void Mult (int *, int *);
void Div (int *, int *);
void Put (int *);
bool Smaller (int *, int *);
void Shift (int *, int);
void Mult (int *a, int *b) {
int s = LEN;
while (--s >= 0 && !a[s]) {}
int t = LEN;
while (--t >= 0 && !b[t]) {}
int c[LEN];
memset (c, 0, sizeof (c));
for (int i=0; i<=s; ++i) {
for (int k=0; k<=t && i+k<LEN; ++k) {
c[i + k] += a[i] * b[k];
}
}
int car = 0;
for (int i=0; i<LEN; ++i) {
int t = car + c[i];
c[i] = t % 10;
car = t / 10;
}
assert (car == 0);
memcpy (a, c, sizeof (c));
}
void Put (int *a) {
int i = LEN;
while (--i > 0 && !a[i]) {}
while (i >= 0) {
printf ("%d", a[i--]);
}
printf ("\n");
}
bool Smaller (int *a, int *b) {
for (int i=LEN-1; i>=0; --i) {
if (a [i] > b [i]) {
return false;
} else if (a [i] < b [i]) {
return true;
}
}
return false;
}
void Shift (int *a, int sh) {
if (sh < 0) {
sh = -sh;
for (int i=0; i<LEN-sh; ++i) {
a[i] = a[sh + i];
}
for (int i=LEN-sh; i<LEN; ++i) {
a[i] = 0;
}
} else if (sh > 0) {
for (int i=LEN-1; i>=sh; --i) {
a[i] = a[i - sh];
}
for (int i=sh-1; i>=0; --i) {
a[i] = 0;
}
}
}
void Div (int *a, int *d) {
int i = LEN;
while (--i >= 0 && !a[i]) {}
int k = LEN;
while (--k >= 0 && !d[k]) {}
if (i < k) {
memset (a, 0, sizeof (a));
return;
}
Shift (d, i - k);
static int res[LEN];
memset (res, 0, sizeof (res));
i -= k;
while (i >= 0) {
while (! Smaller (a, d)) {
Sub (a, d);
++res[i];
}
#ifdef _DEBUG
printf ("\n");
Put (a);
Put (d);
Put (res);
#endif
--i;
Shift (d, -1); // divided by 10 (the radix)
}
memcpy (d, a, sizeof (*a) * LEN);
memcpy (a, res, sizeof (res));
}
void Sub (int *a, int *b) {
int bor = 0; // borrow
for (int i=0; i<LEN; ++i) {
int t = a[i] - b[i] - bor;
a[i] = (t + 10) % 10;
bor = 1 - (t + 10) / 10;
}
assert (bor == 0);
}
#define FACS 320
int fac[FACS][LEN];
int main () {
memset (fac, 0, sizeof (fac));
fac[0][0] = 1;
for (int i=1; i<FACS; ++i) {
fac[i][0] = i % 10;
fac[i][1] = i / 10 % 10;
fac[i][2] = i / 100;
Mult (fac[i], fac[i - 1]);
#ifdef _DEBUG
Put (fac[i]);
#endif
}
int n;
while (scanf ("%d", &n) == 1 && n) {
static int a[100];
int sum = 0;
for (int i=0; i<n; ++i) {
scanf ("%d", &a[i]);
sum += a[i];
}
static int res[LEN];
memcpy (res, fac[sum], sizeof (res));
static int div[LEN];
memset (div, 0, sizeof (div));
div[0] = 1;
for (int i=0; i<n; ++i) {
Mult (div, fac[a[i]]);
}
Div (res, div);
Put (res);
}
return 0;
}