HDU 1261(字串数)

组合数量为 (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;
}

继续加油。

发布了206 篇原创文章 · 获赞 1 · 访问量 9002

猜你喜欢

转载自blog.csdn.net/Intelligence1028/article/details/104783299