【GZOJ】1372——阶乘

原创 2015年11月18日 16:12:48

题目链接广大OJ1372
本题亦为广大15级第一次周赛的J题。

题目内容

Problem Description
阶乘的计算公式是:n!=1*2*3*4*5*……*n

例如说,2的阶乘是2,3的阶乘是6

现在要做的程序是,输入一个数n,输出n的阶乘。

Input
多组输入数据。

每组输入数据占一行,为一个整数n(1<=n<=5000)

Output
对于每组输入,输出n的阶乘,占一行。
Sample Input
3
2
Sample Output
6
2
Hint
注意细节。

解题思路

所谓细节就是,n的最大值可以是5000。这意味着n的阶乘会非常大,大到连long long都无法储存。
对于这种题,用Java的大整数类解决无疑是最方便也是最快的。不过这里讨论的是C或者C++的解法,也就是高精度算法中的大整数数乘以小整数。
高精度算法的核心思想就是,使用一个数组来储存一个大数,按位储存。
例如说,用这个方法储存数字182738,就可以建一个数组a[],令a[0]=1,a[1]=8,a[2]=2,a[3]=7,a[4]=3,a[5]=8。当然也可以反过来(反过来的话计算会方便一些)。
然后是高精度数字的计算方法。高精度数字的加减乘除其实可以参考我们小学所学的竖式运算方式,容易理解而已也很好用。(所以我们小学是学了什么不得了的东西了吗= =)
例如说这道题需要到的大整数乘以小整数,以1872381*8为例。
按照竖式运算,乘法是从个位开始进行逐位乘上去的(所以反向储存就比较方便),然后遇到乘积大于10的就要进位。按照这样的方法我们可以这么计算:
答案的个位是1*8=8,无需进位。
答案的十位是8*8=64,需进位6,答案修正为4。
答案的百位是3*8+6=30,需进位3,答案修正为0。
答案的千位是2*8+3=19,需进位1,答案修正为9。
答案的万位是7*8+1=57,需进位5,答案修正为7。
答案的十万位是8*8+5=69,需进位6,答案修正为9。
答案的百万位是1*8+6=14,需进位1,答案修正为4。
由于还存在进位,所以答案有了千万位,为1。
将这些为连起来就是答案:14979048。
上述方法其实就是小学的竖式运算的步骤。只需要贯彻“按位储存”的思想,以及不要忽视进位就可以了。
阶乘的计算便无需多说了,就是高精度乘法的多次调用而已。

代码

#include<iostream>
using namespace std;
void f(int *a,int n,int &al)//这里的大整数是用数组a反向储存
{
    for(int i=2;i<=n;i++)//让a从2乘到n
    {
        int p=0,j;//变量p用于储存进位,初始化为0
        for(j=0;j<al||p!=0;j++)//当进位不为0时还需继续运算
        {
            a[j]*=i;
            a[j]+=p;
            p=0;
            if(a[j]>10)//是否需要进位
            {
                p=a[j]/10;
                a[j]%=10;
            }
        }
        al=j;//重置长度
    }
}
int main()
{
    int n;
    while(cin>>n)
    {
        int a[100000]={0};
        a[0]=1;
        int al=1;
        f(a,n,al);//变量al用于储存数组长度
        for(int i=al-1;i>=0;i--)cout<<a[i];//倒序输出
        cout<<endl;
    }
}
版权声明:本文为博主原创文章,未经博主允许不得转载。

【GZOJ】1367——A*B问题

广大15级第一次周赛A题
  • Mach_Cap
  • Mach_Cap
  • 2015年11月17日 15:57
  • 333

【GZOJ】1370——名为F的数列

题目链接:广大OJ1370 本题亦为广大15级第一次周赛的D题。题目内容Problem Description 数学上定义斐波那契数列(简称F数列)的递推公式为:F[n]=F[n-1]+F[n-2...
  • Mach_Cap
  • Mach_Cap
  • 2015年11月17日 21:44
  • 328

hdu1372 dfs搜索之国际象棋的马

中国象棋和国际象棋应该还是有些渊源的,的确二者的起源不同。中国象棋在战国以前就有了,而国际象棋流行的说法是起源于古印度。二者在千百年的历史长河中,其规则和形态也都是在一直变化的。中国古代很早就和印度有...
  • guodongxiaren
  • guodongxiaren
  • 2014年07月05日 12:38
  • 1705

hdu1372(最爱的广搜)

Description A friend of you is doing research on the Traveling Knight Problem (TKP) where you are t...
  • martinue
  • martinue
  • 2015年08月05日 20:37
  • 220

python爬虫入门

Python爬虫入门八之Beautiful Soup的用法 Python之lxml库学习笔记一 libxml2-python-2.7.7.win32-py2.7.exe...
  • ztf312
  • ztf312
  • 2015年11月02日 21:15
  • 691

求阶乘 递归实现和非递归实现

一个数的阶乘就是这个数连乘每个比前一个数小1的数,例如5的阶乘是:5 * 4 * 3 * 2 * 1,  0和1的阶乘是1.用公式实现: fac(n) =           1           ...
  • NaN_Lovelance
  • NaN_Lovelance
  • 2016年09月04日 16:01
  • 7481

undefined reference to `uglIoDrvInit'

今天在vx6.7下面编译windml5.2遇到下面的报错。 问题:partialImage.o: In function `usrWindMlInit': C:/WindRiver/compone...
  • Blaider
  • Blaider
  • 2014年01月04日 12:23
  • 1847

大数据之大数阶乘

描述 我们都知道如何计算一个数的阶乘,可是,如果这个数很大呢,我们该如何去计算它并输出它? 输入 输入一个整数m(050样例输出304140932017133780436126081660647...
  • qq_26138699
  • qq_26138699
  • 2017年06月01日 14:18
  • 178

HDU 1372 HDU 1372

Knight Moves Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) T...
  • Xuan_James
  • Xuan_James
  • 2016年03月22日 17:04
  • 170

迭代求阶乘

# include /** * 时间:2016年6月5日 11:22:23 * 内容:迭代 * 任何使用递归的方法都可以使用迭代来代替 */ long Iterator_Factor...
  • Notzuonotdied
  • Notzuonotdied
  • 2016年06月09日 21:32
  • 897
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:【GZOJ】1372——阶乘
举报原因:
原因补充:

(最多只允许输入30个字)