算法訓練 P0505

一個整數n的階乘可以寫成n!,它表示從1到n這n個整數的乘積。階乘的增長速度非常快,例如,13!就已經比較大了,已經無法存放在一個整型變量中;而35!就更大了,它已經無法存放在一個浮點型變量中。因此,當n比較大時,去計算n!是非常困難的。幸運的是,在本題中,我們的任務不是去計算n!,而是去計算n!最右邊的那個非0的數字是多少。例如,5!=1*2*3*4*5=120,因此5!最右邊的那個非0的數字是2。再如,7!=5040,因此7!最右邊的那個非0的數字是4。再如,15!= 1307674368000,因此15!最右邊的那個非0的數字是8。請編寫一個程序,輸入一個整數n(0<n<=100),然後輸出n!最右邊的那個非0的數字是多少。
輸入:
  7
輸出:
  4

/*在這裏我們採用數組保存大數 的方法,但是跟常規的方法比較不一樣的是,我們採用1000進制的方式來存
儲,這樣子的話我們可以節省開闢的數組空間和計算步驟,具體步驟跟10進制是一樣的,還是很容易理解的*/
#include<iostream>
#include<algorithm>
#include<cstring>
using namespace std;

int main()
{
	int n;
	cin >> n;
	int a[1000];
	memset(a,0,sizeof(a));
	a[0] = 1;
	int c,sum;
	for(int i = 2;i <= n;i++)
	{
		c = 0;
		for(int j = 0;j < 1000;j++)
		{
			sum = a[j] * i + c;
			a[j] = sum % 1000;
			c = sum / 1000;
		}
	}
   /*******************************************/
    /*這一部分可以用來打印階乘的計算結果,方便我們檢驗結果是否正確*/
   /*	for(int i = 999;i >= 0;i--)
	{
		if(a[i] != 0)
		{
			c = i;
			break;
		}
	}
	cout << a[c];
	for(int i = c-1;i >= 0;i--)
	{
		if(a[i] < 10)
		{
			cout << 0 << 0;
		}
		else if(a[i] < 100)
		{
			cout << 0;
		}
		cout << a[i];
	}
	cout << endl;            */
 /**********************************************/

 /*我們只要從數組的第0位開始檢測找到第一個非零的數就可以得出結果了,不過有一點需要注意,就是由於
我們是用1000進制來保存的,也就是我們找到非零的數之後,還需要進行簡單的分析,比如是個位我們可以直
接輸出,是2位或者3位的話,我們就按10取餘,如果爲0,就繼續 %10 ,直到得到非零的 一位整數 就可以了 */
	for(int i = 0;i < 1000;i++)
	{
		if(a[i] != 0)
		{
			if(a[i] < 10)
			{
				cout << a[i];
			}
			else
			{
				while(a[i]%10 == 0)   //如果按10取餘之後是0,那麼接着取第2位、第3位,依次類推
				{
					a[i] /= 10;
				}
				cout << a[i] % 10;
			}
			break;
		}
	}
	return 0;
}

 

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