高精度算法求阶层详解

求N!的值 【问题描述】     用高精度方法,求N!的精确值(N以一般整数输入)。

【输入样例】ni.in    10

【输出样例】ni.out    3628800

本题解题障碍在于,受数据类型取值范围的限制,当N值很大时,阶层的结果放到变量中会造成数据溢出。

解题思路:

        将相乘的结果,以单个的数字逆序存在int[ ] f数组里,f[0]存放当前数组的有效长度。求阶层的每一步中,都是用当前数字乘以数组中的每位数字,因为是逆序存放,所以从f[1]开始乘,每一位乘完的数字处理好进位。

        单步过程以5040*8举例如下(省略了存放有效位数的f[0]):

        step1:高精度算法求阶层详解_第1张图片

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

        step2:高精度算法求阶层详解_第2张图片

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

        积=4*8,需要进位,f[2]=2,把3进位到f[3],f[3]=3+0×8=3

        step3:高精度算法求阶层详解_第3张图片

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

        积=5*8,需要进位,f[4]=0,把4进位到f[5]

        step4:高精度算法求阶层详解_第4张图片

规律:当前j位的结果=f[ ]数组中的j位与当前数i的乘积+上轮进位,s=f[j]*i+c,然后取模留下个位,整除10将其他位存在进位c里,f[j]=s%10;c=s/10;

#include 
#include 
using namespace std;
const int maxn=3000;
int f[maxn];
int main()
{
    int i,j,n;
    cin>>n;
    memset(f,0,sizeof(f));
    f[0]=1;
    f[1]=1;
    /*
    把每次相乘的结果拆成单个数字放在数组f[]里,每个数字乘当前数,再把结果拆成单个数字放在数组里,如此循环
	*/
    for (i=2;i<=n;i++)
    {
        //c存放进位
        int c=0;
        for (j=1;j<=f[0];j++)
        {
            int s=f[j]*i+c;
            f[j]=s%10;
            c=s/10;
            /*wanziwu改进,之前是for (j=0;j0)
            {
            	f[0]++;
			}
        }
    }
    for (i=f[0];i>0;i--)
        cout<

 

你可能感兴趣的:(信息学)