HDU1042 N!

N!

Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 262144/262144 K (Java/Others)
Total Submission(s): 70821    Accepted Submission(s): 20307


Problem Description
Given an integer N(0 ≤ N ≤ 10000), your task is to calculate N!
 

Input
One N in one line, process to the end of file.
 

Output
For each N, output N! in one line.
 

Sample Input
  
  
1 2 3
 

Sample Output
  
  
1 2 6
 
题目大意:
题目意思很简单,就是求N!,也就是求N的阶乘,1*2*3*4*.......*n;
分析:
求N!,我们知道在C++中用64位的整型保存的话,最多可以求出20!,所以一看便知道这题不是简单的求N!,而是一个大数问题,大数问题的话,我们首先想到的是用字符串去模拟大数加减乘除,但是这里求N!我们其实可以用到整型数组去模拟进制的进位(知道这个思路去做,也是实验室的小伙伴讲题的时候告诉我们的,在这里感谢 徐海文 童鞋,给我带来的思路);

我们在这里开一个足够大的数组,平时的话我们是用十进制去算数,也就是满了9就进一位,这里的话我们用 一万进制数去计算(这个进制的意思和八进制,十六进制意义有点不一样,仔细去看就会明白恩),也就是满9999就向前进位,我们用整型数组开模拟进位的过程,假设需要存放的数字为 2345678 我们将其存放到整型数组 num[]中有,num[1]=234,num[0]=5678;   再如数字:1210000     num[1]=121,num[0]=0; 是不是可以理解了恩,那么也就是每个整型数组中的每一个位置都可以存放小于10000的数,当数大于等于10000时,我们就要将其大的数放到数组的下一个位置。但是由于这种模拟过程会出现 num[]数组中有 等于0 的情况,那如果按正常输出的话就会出现 1210000   ==>1210了   这时候我们其实只要控制输出格式就好了 用printf("%04d",num[0]);就好了;

上面的这些都理解了,那么我们就开始这题的讲解恩,因为是求N!,而且N的最大值可能达到10000   那么就会出现非常大的数据,  比如我们得到的是 123456789123456 *25的话,其实就变成了num[0]=3456,     num[1]=8912,       num[2]=4567,   num[3]=123, 就变成了 num[0]*25,  num[1]*25,   num[2]*25,    num[3]*123;如果出现了大于等于10000的数据,那么我们就将其大的加到前面的数组中;

num0123
数据345689124567123

分别乘以*25
num0123
数据3456*258912*254567*25123*25


然后就变成这样了:
num0123
数据864002228001141753075

将数组的每个位置大于等于10000的加到前面的数组中:
num0123
数据64002800+84175+223075+11

然后再从数组的最后一位开始往前面输出,就可以得到答案了;

给出AC代码:
#include<iostream>
#include<cstring>
#include<string>

using namespace std;

int main()
{
	int a[50000];
	int n;
	while (~scanf("%d",&n))
	{
		memset(a, 0, sizeof(a));
		a[0] = 1;
		int count = 0;
		for (int i = 2; i <= n; i++)
		{
			for (int j = 0; j <= count; j++)
				a[j] *= i;
		for (int j = 0; j <= count; j++)
		{
			int temp = a[j] / 10000;
			a[j + 1] += temp;
			//cout << "a[j]=" << a[j] << endl;
			a[j] = a[j] % 10000;
			//cout << a[j + 1] <<"  "<<a[j] << endl;
		}
			if (a[count + 1]>0)count++;    //保证数组的空间足够存放下该大数据;
		}
		printf("%d", a[count]);
		for (int i = count - 1; i >= 0; i--)
		{
			printf("%04d", a[i]);
		}
		printf("\n");
	}
	return 0;
}




  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值