题目链接
http://acm.hdu.edu.cn/showproblem.php?pid=1042
题目要求
求解任意给定数N(0 ≤ N ≤ 10000)的阶乘结果。
求解思路
显然,使用int型直接进行计算是不行的,int的范围是21亿左右,100的阶乘就要超过这个数字,这里采用别的办法。
求解过程:
虽然大一曾经做过一个大数乘法程序(用数组,每位有五个数字),这次尝试了用字符串+打表的形式计算,果然字符串计算慢是出了名的。下面是使用字符串的C++代码
#include<iostream>
#include<string>
#include<sstream>
#include <algorithm>
using namespace std;
int main()
{
string s = "1";
stringstream ss, ss2;
string end[10000];
string endstring, nextstring;
int num, next, carry = 0;
for (int i = 1; i <= 10000; ++i)
{
int j = s.length();
int temp;
int k = 1;
endstring = "";
carry = 0;
//reverse(s.begin(), s.end());
for (; k <= j; ++k)
{
ss.clear();
ss << s[k - 1];
ss >> temp;
next = temp*i + carry;
carry = next / 10;
ss2.clear();
ss2.str("");
ss2 << next % 10;
nextstring = ss2.str(); //stringstream
endstring += nextstring;
}
if (carry != 0)
{
//cout << "---carry---" << carry << endl;
ss2.clear();
ss2.str("");
ss2 << carry;
endstring += ss2.str();
}
s = endstring;
string tempstring(s.rbegin(), s.rend());
end[i] = tempstring;
}
while (true)
{
cin >> num;
cout << end[num] << endl;
}
return 0;
}
运行速度较慢,可以将外层for循环中的”i<=10000”改为”i<=1000”
当然这样做是会超时的,string类实在是太慢了。
下面是采用数组的大数乘法,每个数组有五位数,未打表。
#include<stdio.h>
int main()
{
int num[10001], carry,n,m;
while (~scanf("%d", &n))
{
num[0] = 1;
m = 0;
for (int i = 1; i <= n; ++i)
{
carry = 0;
for (int j = 0; j <= m; ++j)
{
num[j] = num[j] * i + carry;
carry = num[j] / 100000;
num[j] = num[j] % 100000;
}
if (carry > 0) //够五位数有进位,m多一位
{
m++;
num[m] = carry;
}
}
printf("%d", num[m]);
for (int i = m - 1; i >= 0; i--)
{
printf("%05d", num[i]);
}
printf("\n");
}
return 0;
}