http://acm.hdu.edu.cn/showproblem.php?pid=1261
题解
- 令sum=a1+a2+···+an
- 种数为 sum!/(a1!a2!···an!)
- 其中sum最大为25*12,而int能容纳的最大阶乘为12,long long能容纳的最大阶乘不超过50,故这是一个大数乘法的问题。https://blog.csdn.net/wang_1997/article/details/68241892
/a*b=res //a,res均从前往后为个,十,百... void multiply(vector<long long> a,long long b,vector<long long>& res,int& k) { int p=0; int cnt=k; vector<long long> tmp(5000,0); while(b) { int digit=b%10; for(int i=0;i<k;i++) { tmp[p+i]+=digit*a[i]; if(p+i+1>cnt) cnt=p+i+1; } p++; b/=10; } k=cnt; for(int i=0;i<k;i++) { tmp[i+1]+=tmp[i]/10; tmp[i]=tmp[i]%10; } while(tmp[k]) { tmp[k+1]+=tmp[k]/10; tmp[k]=tmp[k]%10; k++; } res=tmp; }
- 由于sum!可能为大数,故又涉及到大数除法的问题。https://blog.csdn.net/z_y1314/article/details/79716387
void divide(vector<long long> a,long long b,vector<long long>& res,int& k) { vector<long long> tmp(5000,0); long long rest=0; int ind=0; for(int i=0;i<k;i++) { rest=rest*10+a[i]; if(ind||rest>=b) { tmp[ind++]=rest/b; rest=rest%b; } } res=tmp; k=ind; }
AC代码
#include<iostream>
using namespace std;
#include<algorithm>
#include<vector>
#define N 250
vector<long long> jc(13);
void init()
{
jc[0]=1;
jc[1]=1;
for(int i=2;i<13;i++)
jc[i]=jc[i-1]*i;
}
/a*b=res
//a,res均从前往后为个,十,百...
void multiply(vector<long long> a,long long b,vector<long long>& res,int& k)
{
int p=0;
int cnt=k;
vector<long long> tmp(5000,0);
while(b)
{
int digit=b%10;
for(int i=0;i<k;i++)
{
tmp[p+i]+=digit*a[i];
if(p+i+1>cnt)
cnt=p+i+1;
}
p++;
b/=10;
}
k=cnt;
for(int i=0;i<k;i++)
{
tmp[i+1]+=tmp[i]/10;
tmp[i]=tmp[i]%10;
}
while(tmp[k])
{
tmp[k+1]+=tmp[k]/10;
tmp[k]=tmp[k]%10;
k++;
}
res=tmp;
}
void divide(vector<long long> a,long long b,vector<long long>& res,int& k)
{
vector<long long> tmp(5000,0);
long long rest=0;
int ind=0;
for(int i=0;i<k;i++)
{
rest=rest*10+a[i];
if(ind||rest>=b)
{
tmp[ind++]=rest/b;
rest=rest%b;
}
}
res=tmp;
k=ind;
}
int main()
{
int n;
init();
while(cin>>n&&n)
{
vector<int> a(n);
int sum=0;
for(int i=0;i<n;i++)
{
cin>>a[i];
sum+=a[i];
}
vector<long long> up(5000,0);
int k=0;
if(sum<=12)
{
long long tmp=jc[sum];
for(int i=0;i<n;i++)
tmp/=jc[a[i]];
cout<<tmp<<endl;
continue;
}
else
{
long long tmp=jc[12];
while(tmp)
{
up[k++]=tmp%10;
tmp/=10;
}
for(int i=13;i<=sum;i++)
{
multiply(up,i,up,k);
}
reverse(up.begin(),up.begin()+k);
for(int i=0;i<n;i++)
{
divide(up,jc[a[i]],up,k);
}
for(int i=0;i<k;i++)
{
cout<<up[i];
}
cout<<endl;
}
}
return 0;
}