现在的位置: 首页 > 综合 > 正文

字符串数目

2013年06月08日 ⁄ 综合 ⁄ 共 1362字 ⁄ 字号 评论关闭

问题描述: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;
}

抱歉!评论已关闭.