问题描述:http://acm.hdu.edu.cn/showproblem.php?pid=1261
// 1261字串数.cpp : (a1+a2+ ... +an)! / a1! / a2! / ... / an! #include "stdafx.h" #include <iostream> #include <string> #include <vector> using namespace std; const int TYPE = 26; const int MAX = 13; vector<string> Facs;//阶乘 void convert(string& str)//字符串首尾倒置 { int i=0,Size=str.size(),half=Size/2; for(;i<half;++i) swap(str[i],str[Size-1-i]); } string Multiply(const string& a,int b) { string result; int carry=0,i,Size=a.size(),c; for(i=Size-1;i>=0;--i)//从低位开始,高位在前;从低位往高位运算,从而在高位处可以实现继续往高位进位,而除法不同,采取的是从高位往低位进行运算 { c = (a[i]-'0')*b + carry; carry = c/10; c %= 10; result.push_back(c+'0'); } while(carry) { c = carry%10; carry /= 10; result.push_back(c+'0'); } convert(result);//因为是从低位开始计算的,所以将低位运算的结果放到数组的首位置(高位里面)了,因此最后需要进行逆置 return result; } string Divide(const string& a,int b) { string result; int carry=0,i,Size=a.size(),c; for(i=0;i<Size;++i)//从高位开始除,高位在前,高位开始计算之后将计算结果又放到数组的开头部分(高位),故就没有必要进行逆置 { c = (a[i]-'0')+carry*10; carry = c%b; c /= b; if(c==0&&result.size()==0) continue; else result.push_back(c+'0'); } return result; } void CalFacs() { Facs.push_back("1"); Facs.push_back("1"); Facs.push_back("2"); string ans = "2"; for(int i=3;i<=26*12;++i) { ans = Multiply(ans,i); Facs.push_back(ans); } } int main() { CalFacs(); int N,Sum,i,j; string ans; while(cin>>N) { if(N==0)break; Sum = 0; vector<int> Num(N); for(i=0;i<N;++i) { cin>>Num[i]; Sum+=Num[i]; } ans = Facs[Sum]; for(i=0;i<N;++i) { for(j=2;j<=Num[i];++j) ans = Divide(ans,j); } cout<<ans<<endl; } return 0; }