N!

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


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
 

Author
JGShining(极光炫影)
(题目来源于hdu http://acm.hdu.edu.cn/showproblem.php?pid=1042)

解题思路

围绕了大数乘法这个理念,我在这里运用了两种方法。。。。。。

一个是利用了字符串来进行模拟乘法,另外一种则是利用了大数组来储存n!每一位的数字然后进行模拟


利用字符串来进行模拟

这种做法不是最好的但是我觉得挺好理解的所以想和大家分享一下~

这里我需要用到大数加法的知识,所以如果还没有了解大数加法的同学可以去我的博客里面看一下大菲波数那篇文章噢!

好啦,言归正传,我想问问大家对于乘法有什么理解。

比如说1236548*5124;

首先,我们会把位数小的放在下面,类似于

1236548

      5124

------------

这样子对吧,然后我们用4来乘8,得32,在小横杠上写上一个3,然后4*4=16,16+3=19,在小横杠上写一个1......

我们的大数乘法就是模拟这一种方法!

string mulSingle(string s, char a)//计算单个乘积(这里的char其实就是我们提取,类似5124,提取4、2、1、5
{
	int sum = 0;
	int flag = 0;
	string part;
	for (int i = s.size() - 1; i >= 0; i--)
	{
		int sum = flag + (a - '0')*(s[i] - '0');//是指你的进位数 例如4*8=32,flag=3
		part = part + char(sum % 10 + '0');//%10是取进制后的数字,例如32%10=2;
		flag = sum / 10;
		if (i == 0)
			part = part + char(flag + '0');//例如4*8236548乘完了每一位数字,最后还有进制,则相对应加上
		for (int i = 0; i < part.size() / 2; i++)//进行转置
		{
			char tmp = part[i];
			part[i] = part[part.size() - 1 - i];
			part[part.size() - 1 - i] = tmp;
		}
	}
	return part;
}

小伙伴们肯定发现了,这里只是处理了一次啊,1236548*5124还有2、1、5没有处理呢

string mulAll(string s, string s2)
{
	string tmp;
	string all;
	for (int i = s2.size() - 1, k = 0; i >= 0; i--, k++)
	{
		tmp = mulSingle(s, s2[i]);//对5124的每一位都进行这样子的操作
		for (int j = 0; j < k; j++)
		{
			tmp = tmp + '0';
		}
		all = add(tmp, all);
	}
	return all;
}

上面程序的重点

		for (int j = 0; j < k; j++)
		{
			tmp = tmp + '0';
		}
为什么要这样子做?因为类似12*25

                        12

                        25

------------------------

                        60                                         60

                       24(注意这里有偏位)等价于240

-------------------------

                        300


我想你应该能明白为什么要这样子写了


利用大数组来储存n!的每一位进行模拟乘法

具体的思路就是

每一位的储存起来,然后利用i(i从2一直自增到n)乘每一位数字,然后模拟进制!

在这里我想跟大家探讨一下乘法的新角度

例如

756*5

            7 5 6

                  5


-----------------

我想很多人都是,30,进3,25,25+3=28,进2,7*5=35,35+2=37进3,最后答案就是3780

但是大家有没有想过,我们其实可以先都算出来

(35)(25)(30)

这样子,首先(35)(28)0

然后(37)80

最后3780

有没有发现!完全一样!

这也是我们这种观法的特别之处!

我们的数组的每一个下标,都是一个int!可以超过10的!这样子操作真的太方便了!

最后还有一个细节,就是我们如何初始化我们的数组,大家可以思考一下。0?

最后贴上代码,分别对应了字符串和数组的两种算法。

http://paste.ubuntu.com/25233762/

http://paste.ubuntu.com/25233754/


最后,字符串算法无法处理到10000,但是数组算法是妥妥的~我也不知道为什么。。。。。。可能string【10000】太大了。。。。。。

这个我先和别的同学、前辈多交流,交流完后即时和大家汇报~

大家也可以和我说说你们的看法噢!

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值