藍橋杯練習系統 基礎練習(vip試題):BASIC-30 階乘計算

題目信息

問題描述

 輸入一個正整數n,輸出n!的值。
 其中n!=123*…*n。

算法描述

 n!可能很大,而計算機能表示的整數範圍有限,需要使用高精度計算的方法。使用一個數組A來表示一個大整數a,A[0]表示a的個位,A[1]表示a的十位,依次類推。
 將a乘以一個整數k變爲將數組A的每一個元素都乘以k,請注意處理相應的進位。
 首先將a設爲1,然後乘2,乘3,當乘到n時,即得到了n!的值。

輸入格式

 輸入包含一個正整數n,n<=1000。

輸出格式

 輸出n!的準確值。

樣例輸入

10

樣例輸出

3628800


解題思路

主要考察

 本題給出的主要考察關鍵字是:高精度。首先我們要明白什麼是高精度算法:

 高精度算法,屬於處理大數字的數學計算方法。在一般的科學計算中,會經常算到小數點後幾百位或者更多,當然也可能是幾千億幾百億的大數字。一般這類數字我們統稱爲高精度數,高精度算法是用計算機對於超大數據的一種模擬加,減,乘,除,乘方,階乘,開方等運算。對於非常龐大的數字無法在計算機中正常存儲,於是,將這個數字拆開,拆成一位一位的,或者是四位四位的存儲到一個數組中, 用一個數組去表示一個數字,這樣這個數字就被稱爲是高精度數。高精度算法就是能處理高精度數各種運算的算法,但又因其特殊性,故從普通數的算法中分離,自成一家。

通過上面的解釋再加上題目提供的算法描述,我們就可以明白如何使用高精度算法來求一個數的階乘了。

解題思路

 如果已經明白了後面這段文字可以跳過,直接看代碼,代碼裏也有相應的解釋。計算過程實際上就是在模擬我們算乘法的過程,我們將存大數的數組初始化爲1,然後我們從2開始乘直到相乘到n。比如我們定義存儲的數組爲a[]。我們使a[0]存儲數字的個位,a[1]存儲十位,a[2]存儲百位……依次類推。當我們計算到數字k的時候我們從a[0]開始使數組中的每一個元素乘以k(這也是我們計算乘法的方法),在將每一位乘以k的同時我們要注意進位問題,我們使用一個變量carry來存儲進位並將其初始化爲0。每次的都將(a[i]*k)+carry,即該位數乘以k加上上一次的進位數。然後我們再將該結果對10取模,求出當前結果的個位數並將該數存到當前位置,然後再將該數除以10求出當前結果的進位數。不斷的進行循環最終就可以求出結果。
注意:

  • 計算之前一定要將數組的每一位初始化爲0
  • 由於我們是從低位向高位計算存儲的,所以我們輸出的時候應該倒着輸出,即從高位到低位輸出。這裏我們初始化數組的空間爲4000,如果我們直接倒着輸出肯定會先輸出很多很多的0,所以我們需要倒着遍歷一下數組,直到數組元素不爲0爲止,我們將這個數標記爲k,然後輸出時我們直接從k倒着輸出即可

解題代碼

#include<iostream>
using namespace std;

#define MAX 4000 

int main(){
	int a[MAX] = {0};    //將每一位初始化爲0 
	int n;
	cin>>n;
	a[0] = 1;	//初始化數組中的數爲 1  
	//從 2 一直乘到 n 
	for(int i=2;i<=n;i++){
		int carry = 0;	//用carry記錄進位 
		//每次都將當前數組中存儲的數字乘以 i  
		for(int j=0;j<MAX;j++){
			int t = a[j]*i + carry;	//將數組中當前的數的每一位乘以j,在加上上一位的進位 
			a[j] = t%10;	//將當前位置乘以 i 的結果保存到j位 
			carry = t/10;	//計算進位,如果超過10,保留的會是十位上的數,不超10 carry 爲 0 
			
		}
		
	}
	int k;	//使用k來標記數組的長度 
	for(k = MAX-1;k>=0;k--){
		if(a[k]){
			//在數組中從後往前遍歷,找到第一個不爲0的數,記錄此時數組中k的位置 
			break;
		}
	}
	//輸出結果,因爲我們是按照從低位到高位計算的,但是我們要按照從高位到低位輸出 
	for(int i=k;i>=0;i--){
		cout<<a[i];
	}
	return 0;
} 

 以上就是對於本題的解題思路了。如果你覺得我的文章對你有用請點個贊支持一下吧,喜歡我寫的文章那麼請點個關注再走喲。如果此文章有錯誤或者有不同的見解歡迎評論或者私信。
推了一下眼角膜
我是ACfun:一個成長中的程序猿,感謝大家的支持。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章