1. 程式人生 > >2014年第五屆藍橋杯C/C++程式設計本科B組決賽 出棧次序(結果填空)

2014年第五屆藍橋杯C/C++程式設計本科B組決賽 出棧次序(結果填空)

2014年第五屆藍橋杯C/C++程式設計本科B組決賽題目彙總:


出棧次序

X星球特別講究秩序,所有道路都是單行線。一個甲殼蟲車隊,共16輛車,按照編號先後發車,夾在其它車流中,緩緩前行。
路邊有個死衚衕,只能容一輛車通過,是臨時的檢查站,如圖【p1.png】所示。
X星球太死板,要求每輛路過的車必須進入檢查站,也可能不檢查就放行,也可能仔細檢查。
如果車輛進入檢查站和離開的次序可以任意交錯。那麼,該車隊再次上路後,可能的次序有多少種?
為了方便起見,假設檢查站可容納任意數量的汽車。
顯然,如果車隊只有1輛車,可能次序1種;2輛車可能次序2種;3輛車可能次序5種。

現在足足有16輛車啊,親!需要你計算出可能次序的數目。


題意:求n個元素的出棧情況有多少種。

思路:

方法一:

我們把n個元素的出棧個數的記為f(n), 那麼對於1,2,3, 我們很容易得出:

                                    f(1)= 1     //即 1

                                    f(2)= 2     //即 12、21

                                    f(3)= 5     //即 123、132、213、321、231

然後我們來考慮f(4), 我們給4個元素編號為a,b,c,d, 那麼考慮:元素a只可能出現在1號位置,2號位置,3號位置和4號位置(很容易理解,一共就4個位置,比如abcd,元素a就在1號位置)。

分析:

 1) 如果元素a在1號位置,那麼只可能a進棧,馬上出棧,此時還剩元素b、c、d等待操作,就是子問題f(3);

 2) 如果元素a在2號位置,那麼一定有一個元素比a先出棧,即有f(1)種可能順序(只能是b),還剩c、d,即f(2),    根據乘法原理,一共的順序個數為f(1)* f(2);

 3) 如果元素a在3號位置,那麼一定有兩個元素比1先出棧,即有f(2)種可能順序(只能是b、c),還剩d,即f(1),

根據乘法原理,一共的順序個數為f(2) * f(1);

 4) 如果元素a在4號位置,那麼一定是a先進棧,最後出棧,那麼元素b、c、d的出棧順序即是此小問題的解,即        f(3);

結合所有情況,即f(4) = f(3) +f(2) * f(1) + f(1) * f(2) + f(3);

為了規整化,我們定義f(0) = 1;於是f(4)可以重新寫為:

f(4) = f(0)*f(3) + f(1)*f(2) + f(2) * f(1)+ f(3)*f(0)

然後我們推廣到n,推廣思路和n=4時完全一樣,於是我們可以得到:

f(n) = f(0)*f(n-1) + f(1)*f(n-2) + ... +f(n-1)*f(0)

方法二:Catalan數:C(2n,n)/(n+1) (C(2n,n)表示2n裡取n)或者C(2n,n)-C(2n,n-1)都可以解決。

答案:35357670

#include <iostream>
#include <string.h>
using namespace std;
int main()
{
    int f[20];
    memset(f,0,sizeof(f));
    f[0]=1;
    f[1]=1;
    f[2]=2;
    f[3]=5;
    for(int i=4; i<=16; i++)
    {
        for(int j=0; j<=i-1; j++)
            f[i]+=f[j]*f[i-1-j];
    }
    cout<<f[16]<<endl;
    return 0;
}