1. 程式人生 > >百練3727摘花生

百練3727摘花生

      前幾天在百練看到這題,題意主要是輸入一個二維陣列,行和列不大於100,求從左上點到右下點經過的所有節點值之和的最大值,行走路線只能向下或向右。

      由於有多組資料需要輸入,我就用一個函式處理每組陣列,函式引數為一個數組,和其行和列數。沒想到,一開始就在函式宣告上花了好些時間,int getmax(int,int,int * [100]),其實這個錯誤的,*應該用括號括起來,int getmax(int,int,int (*)[100]),前者表示引數為100指標陣列,後者表示為引數為一個指標,指向有100個元素的一維陣列。在C語言中,括號和下標具有最高的優先順序,所以這裡的括號不能省略。

另外,還嘗試了宣告“動態”二維陣列:int getmax(int,int ,int [*][*]),一般來說,多維陣列除了第一維可以不用指定外,其他維數一定要指定大小,這裡的定義其實是:第一個引數為陣列的第一個下標,第二個引數為陣列的第二個下標,而且定義的時候,陣列必須放在後面。雖然可以申明這樣的函式,結果卻不盡人意,因為每次的呼叫,隨著引數的改變,陣列同樣在改變,由於傳遞的陣列一般是個常量,這就有可能導致未知的錯誤。

      第二步,編寫函式內容。根據題意,假設一個二維陣列num[n][m],每次都是從num[0][0]開始走到num[n-1][m-1]結束,如果只有一行,則返回這一行的和,如果只有一列,則返回這一列的和,即n為1或m為1時,返回值就為各元素之和。如果n 和 m都不是1,可以根據規則,按num[n-1][m-1]把整個陣列分為兩部分,一個是去掉最右邊一列的陣列和一個去掉最下邊一行的陣列,返回值應該就是num[n-1][m-1]加上上邊提到的兩個陣列返回值較大的那個陣列的返回值。現在我們就可以寫一個遞迴函式:

 

這裡,我們還需要一個求較大值的函式max(int ,int),或者巨集:max(a,b) ((a)>(b)?(a):(b)),雖然巨集為直接呼叫,但是巨集引數為表示式的時候,表示式會計算兩次,用巨集還是用函式?

      另外,申明多維陣列的時候,還要注意是否會沒有分配到記憶體空間,這裡我就申明瞭個數組num[100][100][100],結果,執行失敗。

     一切看起來很美好,實際上用此遞迴函式,將會是一個噩夢,如果是3x3的陣列,此函式會呼叫11次,4x4是39次,5x5是139次.....如果是100x100,我估計將會算好幾天,所以這裡用遞迴,完全是行不通。昨天有別個給我一個程式碼:

 

他是從每個輸入開始計算最大值的路徑,結果就ok了