火車進出棧問題(高精度 壓位 質因數分解消除除法)

2021-09-23 13:20:59 字數 2705 閱讀 8054

一列火車n節車廂,依次編號為1,2,3,…,n。

每節車廂有兩種運動方式,進棧與出棧,問n節車廂出棧的可能排列方式有多少種。

輸入格式

輸入乙個整數n,代表火車的車廂數。

輸出格式

輸出乙個整數s表示n節車廂出棧的可能排列方式數量。

資料範圍

1≤n≤60000

輸入樣例:

3輸出樣例:

5題解:本題需要輸出合法的方案個數,可以將進站看做是+, 出站看做是-,總共有2 * n 個位置,任選n個位置放 +, 有c(2 * n, n)中選擇, 期中有c(2 * n, n + 1)個是不合法的,所以總的方案就是c(2 * n, n) - c(2 * n, n + 1);這題的資料比較大,可以用高精度來實現。

方法一:(高精度)

直接進行高精度乘法和除法運算。為了縮小中間結果的位數,採取乘乙個數立刻除乙個數的形式,具體表現為:乘2n除1,乘2n-1除2,乘2n-2除3…。至於為何這樣每次都能夠整除,可歸結為:三個連續的整數連乘必然能被3整除,依次類推到n個整數連乘可以被n整除。

**如下:

#include

#include

#include

using namespace std;

int n;

void

mul(vector<

int>

&v,int a)

while

(t)}

void

div(vector<

int>

&v,int a)

while

(v.size()

>0&&

!v.back()

) v.

pop_back()

;}intmain()

div(ans,n +1)

;for

(int i = ans.

size()

-1;i >=

0;i--

)printf

("%d"

,ans[i]);

return0;

}

但這樣,對於這道題來說會超時,所以我們採用以下方法:

方法二:高精度+壓位+質因數分解

本題的最大資料範圍是六萬,六萬的階乘是個相當大的數,使用高精度乘除法依舊無法在六秒的時間內結束程式,所以,必須採取更加高效的方法。本質的思想就是不進行除法,只做乘法,以此來減少運算次數,提高效率。我們將公式分為兩個部分,a / b。假設a = 2 * 2 * 3 * 5 * 5,b = 2 * 5,那麼我們求a / b時只需計算2 * 3 * 5即可。根據算術基本定理,被除數和除數必然都能夠被分解為若干個質數相乘,所以可以採用此法來避免除法運算。

第一部分:質因數分解消除除法運算

分別求出分子和分母的質因數,求出分子和分母各個質因數的差,就可以直接用乘法來做了

第二部分:高精度壓位提高速度

除了直接使用方法一中高精度乘法進行運算外,還可以使用壓位,將多個數壓入乙個向量來減少運算的次數。

特別需要注意的是,使用了壓位技巧後,輸出時一定要規範化向量各個元素的位數,比如壓9位,除了向量末尾元素不需要進行位數限制外,其他元素一律在輸出時使用%09lld進行格式控制,不足9位的前面補0,否則會導致輸出的數結果不正確。

**如下:

#include

#include

#include

using namespace std;

typedef

long

long ll;

const

int n =

1e6+10;

const ll m =

1e9;

ll prime[n]

;vector a;

void

prime

(int n,

int f)

//質因數分解}if

(n)}

void

mul(

int b)

//高精度乘

while

(t)}

intmain()

for(

int i =

2; i <= n +

1; i++

)prime

(i,-1)

;for

(int i =

2; i <=

2* n; i++

)for

(ll j =

0; j < prime[i]

; j++

)mul

(i);

printf

("%lld"

, a[a.

size()

-1])

;for

(int i = a.

size()

-2; i >=

0; i--

)printf

("%09lld"

, a[i]);

//輸出格式要注意

cout << endl;

return0;

}

火車進出站問題 棧

編號為1,2,n的n輛火車依次進站,給定乙個n的排 列,判斷是否是合法的出站順序?思路 先把出站順序存入,用棧模擬進站的火車,按照出站的順序,依次pop出來,判斷 最後的出站數量能否達到n。include include include using namespace std const int m...

壓位高精度模板

原先是整型陣列每個元素存1個數字,壓位高精是每位存8個數字,這樣可以加速8唄,空間也減小了。可謂是對整形陣列的充分利用。include include include include include include include include include include include in...

壓位高精度模板

不走程式,直接上板子。第乙個板子壓四位,支援帶符號的加減乘。第二個板子壓九位,支援不帶符號的四則運算和取模。都封裝了。include include include using namespace std struct intx bool operator const intx b const bo...