1. 程式人生 > >HDU-1018-Big Number( 這段數學推導我給滿分! && 然而並不想用斯特林公式! )

HDU-1018-Big Number( 這段數學推導我給滿分! && 然而並不想用斯特林公式! )

下面這段數學推理,是大牛xiaonian分析出來。不得不承認,他的分析很不錯。

Posted by xiaonian at 2013-05-04 14:07:10 on Problem 1018
/****************************************************
這題要求n的階乘的位數,如果n較大時,n的階乘必將是一個
很大的數,題中說1<=n<10000000,當n=10000000時可以說n
的階乘將是一個非常巨大的數字,對於處理大數的問題,我
們一般用字串,這題當n取最大值時,就是一千萬個數字相
乘的積,太大了,就算儲存在字串中都有一點困難,而且
一千萬個數字相乘是會涉及到大數的乘法,大數的乘法是比較
耗時的,就算計算出結果一般也會超時。這讓我們不得不拋棄
這種直接的方法。

再想一下,這題是要求n的階乘的位數,而n的階乘是n個數的
乘積,那麼要是我們能把這個問題分解就好了。

在這之前,我們必須要知道一個知識,任意一個正整數a的位數
等於(int)log10(a) + 1;為什麼呢?下面給大家推導一下:

  對於任意一個給定的正整數a,
  假設10^(x-1)<=a<10^x,那麼顯然a的位數為x位,
  又因為
  log10(10^(x-1))<=log10(a)<(log10(10^x))
  即x-1<=log10(a)<x
  則(int)log10(a)=x-1,
  即(int)log10(a)+1=x
  即a的位數是(int)log10(a)+1

我們知道了一個正整數a的位數等於(int)log10(a) + 1,
現在來求n的階乘的位數:
假設A=n!=1*2*3*......*n,那麼我們要求的就是
(int)log10(A)+1,而:
log10(A)=log10(1*2*3*......n)  (根據log10(a*b) = log10(a) + log10(b)有)
        =log10(1)+log10(2)+log10(3)+......+log10(n)
現在我們終於找到方法,問題解決了,我們將求n的階乘的位
數分解成了求n個數對10取對數的和,並且對於其中任意一個數,
都在正常的數字範圍之類。

總結一下:n的階乘的位數等於
		  (int)(log10(1)+log10(2)+log10(3)+......+log10(n)) + 1

根據這個思路我們很容易寫出程式
****************************************************/