组合数量为 (n1 + n2 + ... + nn)! / (n1! * n2! * ... * nn!),使用大数乘法和大数除法,套用模板即可。
#include <iostream>
#include <cstring>
using namespace std;
const int MAXN = 30;
int num[MAXN]; //各个字母的数量
int fac[15]; //1至12的阶乘
int ans[1000]; //组合数,ans[0]代表数的位数
//大数乘法,计算s的阶乘
void mul(int s)
{
ans[0] = ans[1] = 1;
for (int i = 2; i <= s; i++)
{
int carry = 0; //进位
for (int j = 1; j <= ans[0]; j++)
{
ans[j] = ans[j] * i + carry;
carry = ans[j] / 10;
ans[j] %= 10;
}
while (carry > 0)
{
ans[++ans[0]] = carry % 10;
carry /= 10;
}
}
}
//大数除法
void div(int n)
{
for (int i = 0; i < n; i++)
{
if (num[i] == 1)
continue;
__int64 d = 0; //当前被除数
for (int j = ans[0]; j > 0; j--)
{
d = d * 10 + ans[j];
ans[j] = d / fac[num[i]];
d %= fac[num[i]];
}
while (ans[ans[0]] == 0) //更新大数位数
{
--ans[0];
}
}
}
int main()
{
fac[0] = fac[1] = 1;
for (int i = 2; i < 15; i++)
{
fac[i] = fac[i - 1] * i;
}
int n;
while (cin >> n)
{
if (n == 0)
break;
memset(ans, 0, sizeof(ans));
int sum = 0; //字母的总数量
for (int i = 0; i < n; i++)
{
cin >> num[i];
sum += num[i];
}
mul(sum); // ans = (n1 + n2 + ... + nn)!
div(n); // ans /= (n1! * n2! * ... * nn!)
for (int i = ans[0]; i > 0; i--)
cout << ans[i];
cout << endl;
}
return 0;
}
继续加油。