您的位置:首页 > 其它

组合数学 + 大数乘法 + 大数除法 之 hdu 1261 字串数

2015-03-18 00:09 429 查看
//  [3/17/2015 JmingS]
/*
此题可直接推导出公式:
{(A1+A2+……+An)!} / {A1!A2!……An!}


由于 (12×26)! = 312! 只能通过数组来存储,所以又涉及『大数乘法』和『大数除法』,
大数实现的主要思想模拟手算,具体参考程序。

*/
#include <iostream>
#include <cstdlib>
#include <cstdio>
#include <cstring>
using namespace std;
const int MAX = 800;

int n, arr[30];
int total;
int Ans[MAX], len;

// 阶乘
void Factorial(int _n, int _arr[], int &_len) {
for (int num = 2; num <= _n; ++num) {
int cnt = 0, val, carry = 0;
for (; cnt < _len; ++cnt) {
val = _arr[cnt] * num + carry;
_arr[cnt] = val % 10;
carry = val / 10;
}
while (carry) {
_arr[_len++] = carry % 10;
carry /= 10;
}
}
}

// 大数除法
void Div(int data) {
int carry = 0;
int val;
for (int i = len - 1; i >= 0; --i) {
val = Ans[i] + carry * 10;
Ans[i] = val / data;
carry = val%data;
}
while (0 == Ans[len - 1]) {
--len;
}
}

void Solve() {
for (int i = 0; i < n; ++i) {
for (int j = 2; j <= arr[i]; ++j) {
Div(j);
}
}
}

int main()
{
//freopen("input.txt", "r", stdin);
//freopen("output.txt", "w", stdout);
while (~scanf("%d", &n) && n) {
total = 0;
for (int i = 0; i < n; ++i) {
scanf("%d", &arr[i]);
total += arr[i];
}
Ans[0] = 1;
len = 1;
Factorial(total, Ans, len);
Solve();
for (int i = len - 1; i >= 0; --i) {
printf("%d", Ans[i]);
}
printf("\n");
}
return 0;
}

                                            
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: