1. 程式人生 > 其它 >資訊學奧賽一本通 1091:求階乘的和 | OpenJudge NOI 1.5 34

資訊學奧賽一本通 1091:求階乘的和 | OpenJudge NOI 1.5 34

技術標籤:C++基礎資訊學奧賽一本通題解OpenJudge NOI題解c++

【題目連結】

ybt 1091:求階乘的和
OpenJudge NOI 1.5 34:求階乘的和

【題目考點】

1. 求一個數的階乘

假設求n的階乘,設結果變數為r,其初值為1。
i從1迴圈到n,每次迴圈將i與r相乘,結果賦值給r。
最後得到的r就是階乘的結果

int f(int n)//求n的階乘函式,返回值是n的階乘。
{
    int r = 1;
    for(int i = 1; i <= n; ++i)
	    r *= i;
	return r;
}

2. 求和

3. 迴圈巢狀

【思路及題解程式碼】

解法1:迴圈巢狀

將求階乘的邏輯寫在求和的迴圈的內部,形成迴圈巢狀。
該解法時間複雜度: O ( n 2 ) O(n^2) O(n2)

#include <bits/stdc++.h>
using namespace std;
int main()
{
    int n;
    cin>>n;
    int sum = 0, v;//v:某一階乘項的值
    for(int i = 1; i <= n; ++i)
    {
        v = 1;
        for (int j = 1; j <= i; ++j)
            v *
= j; sum += v; } cout<<sum; return 0; }

解法2:設求階乘函式

設定階乘函式,每次呼叫階乘函式求一個數的階乘,而後將n個數的階乘加和。
該解法時間複雜度: O ( n 2 ) O(n^2) O(n2)

#include <bits/stdc++.h>
using namespace std;
int f(int n)//求n的階乘 
{
    int r = 1;
    for (int i = 1; i <= n; ++i)
        r *= i;
    return r;
}
int main() { int n; cin>>n; int sum = 0; for(int i = 1; i <= n; ++i) sum += f(i); cout<<sum; return 0; }

解法3:迭代

觀察階乘加和公式,第1項是 1 ! 1! 1!,第2項是 2 ! 2! 2!,…,第i-1項是 ( i − 1 ) ! (i-1)! (i1)!,第i項是 i ! i! i!
已知 i ! = i ⋅ ( i − 1 ) ! i! = i \cdot (i-1)! i!=i(i1)!
只需要設變數v表示某一項的值,初值為1。
每次迴圈,對v乘以i,即可得到新的一項(i的階乘),並將該項加入和sum中。
該解法的時間複雜度為 O ( n ) O(n) O(n),優於解法1,2。

#include <bits/stdc++.h>
using namespace std;
int main()
{
    int n;
    cin>>n;
    int sum = 0, v = 1;//v:某一階乘項的值 
    for(int i = 1; i <= n; ++i)
    {
        v *= i;//本句執行結束後,v的值為i! 
        sum += v;//加和變數中增加i! 
    }
    cout<<sum;
    return 0;
}