1. 程式人生 > >51Nod-1057-N的階乘

51Nod-1057-N的階乘

輸入N求N的階乘的準確值。
Input
輸入N(1 <= N <= 10000)
Output
輸出N的階乘
Input示例
5
Output示例
120

遇見這道題,也是我的運氣,因為以前根本沒有想過這種高精度的題還可以這樣子做,太神奇了,先發一下我原來的做法。

#include <stdio.h>
#include <string.h>
#define _MAX 6
#define MAX_ 10000000
int product[MAX_];
int pro[MAX_], num[_MAX];
int rank = 1;

//遞迴進位函式
void Carrying(int
tag,int i,int j,int *p) { p[i+j]+=tag; if (i + j + 1 > rank || (i + j + 1 == rank && p[i + j] > 9)) { rank++; } if (p[i+j]>9) { tag=p[i+j]/10; p[i+j] %=10; Carrying(tag, i+1, j, p); //寫成Carrying(tag, i, j+1, p);也成立,為了讓i+j遞增而已
} return ; } //乘法 void multiplication(int N) { int i=0,j=0,numLen,productLen,tag; for (i = 0; N > 0; i++) { num[i] = N % 10; N /= 10; } numLen = i; productLen = rank; for (i = 0; i < productLen; i++) { pro[i] = product[i]; } memset
(product, 0, sizeof(int) * MAX_); //逐位相乘 for (i=0; i<productLen; i++) { for (j=0; j<numLen; j++) { tag= pro[i] * num[j]; Carrying(tag, i, j, product); //遞迴 } } return ; } int main() { int N, i = 2, j; scanf("%d", &N); memset(product, 0, sizeof(int) * MAX_); //初始化product資料為0 product[0] = 1; for (; i <= N; i++) { multiplication(i); } //倒序輸出結果 for (j = rank - 1; j >= 0; j--) { printf("%d",product[j]); } printf("\n"); }

這種做法比較細碎,所以在這道題的測試資料下,只過了五分之二的測試資料,剩下的悉數超時,所以,我不得不尋求其他更簡單的方法,於是乎,就遇見了下面這個巧妙的方法。

#include <stdio.h>
#define _MAX 100000000
int main()
{
    int n, i, j, m;
    long long a[10000], c;
    scanf("%d",&n);

    m = 0;
    a[0] = 1;
    for(i = 1; i <= n; i++)
    {
        c = 0;
        for(j = 0; j <= m; j++)
        {
            a[j] = a[j] * i + c;
            c = a[j] / _MAX;
            a[j] %= _MAX;
        }
        if(c > 0)
        {
            m++;
            a[m] = c;
        }
    }
    printf("%lld", a[m]);
    for(i = m - 1; i >= 0; i--)
        printf("%0.8lld", a[i]);
    printf("\n");
    return 0;
}

這裡我們知道,如果簡單的用乘法去階乘,那麼不用多大,立馬就爆了資料範圍,於是,這道題的這個解法巧妙的對這個超級大的數進行了切分,具體切成多寬的看個人愛好,只要能夠用幾個資料型別裝下來就好,這裡我們劃分成了8個的寬度,每八位存一下,最後再進行格式化輸出,巧妙的避開了爆資料範圍的問題。看著程式碼理解起來並不難,提示一下,c和進位相關,m和切的段數相關,就這樣,相信大家看看都是可以理解的,如果無法理解,那麼只能說,回去學學數學吧,乖Y(^_^)Y!!!