1. 程式人生 > 其它 >P1009 [NOIP1998 普及組] 階乘之和

P1009 [NOIP1998 普及組] 階乘之和

技術標籤:OJ+CSP⭐C/C++程式設計筆記c++演算法動態規劃高精度csp

題目描述

用高精度計算出 S = 1 ! + 2 ! + 3 ! + ⋯ + n ! S = 1 ! + 2 ! + 3 ! + ⋯ + n ! ( n ≤ 50 n ≤ 50 ) S = 1! + 2! + 3! + \cdots + n!S=1!+2!+3!+⋯+n!(n \le 50n≤50) S=1!+2!+3!++n!S=1!+2!+3!++n!n50n50

其中“!”表示階乘,例如: 5 ! = 5 × 4 × 3 × 2 × 15 ! = 5 × 4 × 3 × 2 × 1 5! = 5 \times 4 \times 3 \times 2 \times 15!=5×4×3×2×1

5!=5×4×3×2×15!=5×4×3×2×1

輸入格式

一個正整數 n n n

輸出格式

一個正整數 S S S,表示計算結果。

輸入

3

輸出

9

【資料範圍】

對於 100 % 100 100 \%100% 100%100 的資料, 1 ≤ n ≤ 501 ≤ n ≤ 50 1 \le n \le 501≤n≤50 1n501n50

【其他說明】

注,《深入淺出基礎篇》中使用本題作為例題,但是其資料範圍只有 n \le 20n≤20,使用書中的程式碼無法通過本題。

如果希望通過本題,請繼續學習第八章高精度的知識。

【我建議的參考】

《資訊學奧賽課課通》高精度那一章
《資訊學奧賽一本通,C++版》高精度那一章

【題解】

思路差不多,看看各位喜歡哪個就用哪個。

#include <iostream>
#include <bits/stdc++.h>
using namespace std;
int a[2000];
int b[2000];
int c[2000];
int sum[2000];
void pplus(int *a, int *c)
{
    int jw = 0;
    for (int i = 1; i <= 1000; i++)
    {
        c[i] += a[i] +
jw; jw = c[i] / 10; c[i] %= 10; } } void cheng(int *a, int c) { int jw = 0; for (int i = 1; i <= 1000; i++) { a[i] = a[i] * c + jw; jw = a[i] / 10; a[i] %= 10; } } int main() { int n; cin >> n; a[1] = 1; for (int i = 1; i <= n; i++) { cheng(a, i); pplus(a, c); } bool flag = 0; for (int i = 1000; i >= 1; i--) { if (c[i] != 0) flag = 1; if (flag) cout << c[i]; } }

這一個的記錄是這樣的
在這裡插入圖片描述
下一個是第二個

#include <iostream>
#include <stdio.h>
#include <cstring>
#include <cstdlib>
using namespace std;
int n, h, a[1000];
int k;
int anslen;
int nums[1000], ans[10000], c[1000];
void cheng(int n);
void jia()
{
    int jw = 0;
    anslen = h;
    for (int i = 1; i <= h; i++)
    {
        ans[i] += a[i];
        if (ans[i] >= 10)
        {
            ans[i + 1] += 1;
            ans[i] %= 10;
        }
    }
    while (ans[h + 1] > 0)
    {
        anslen++;
    }
}
void cheng(int n)
{
    memset(a, 0, sizeof(a));
    a[1] = 1;
    h = 1;
    for (int i = 2; i <= n; i++)
    {
        for (int j = 1; j <= h; j++)
        {
            a[j] *= i;
        }
        for (int j = 1; j <= h; j++)
        {
            if (a[j] >= 10)
            {
                a[j + 1] += a[j] / 10;
                a[j] %= 10;
            }
        }
        while (a[h + 1] > 0)
        {
            h++;
            a[h + 1] = a[h] / 10;
            a[h] %= 10;
        }
        if (a[h + 1] > 0)
            h++;
    }
}
int main()
{
    memset(nums, 0, sizeof(nums));
    memset(ans, 0, sizeof(ans));
    cin >> k;
    for (int x = 1; x <= k; x++)
    {
        cheng(x);
        // cout << "Factorial : ";
        // for (int i = h; i >= 1; i--)
        // {
        //     cout << a[i];
        // }
        // cout << endl;
        jia();
        // cout << "Current total: ";
        // for (int i = anslen; i >= 1; i--)
        // {
        //     cout << ans[i];
        // }
        // cout << endl;
    }
    for (int i = anslen; i >= 1; i--)
        cout << ans[i];
    cout << endl;
    return 0;
}

測評
在這裡插入圖片描述
第二個更快