題目描述:
該題目來自前兩天騰訊實習生的招聘筆試,題目給出如下的遞歸函數,求ack(3,3)的值。
1 int ack(int m,int n) 2 { 3 if(m == 0) 4 { 5 return n+1; 6 } 7 else if(n == 0) 8 { 9 return ack(m - 1, 1); 10 } 11 else 12 { 13 return ack(m - 1, ack(m, n - 1)); 14 } 15 }
問題解答:
這是一道看起來極其簡單的題目,但是通過簡單的幾步遞歸之后發現,其實預算量並沒有想象中的那么小,筆者在接到這道題后做了大約有8分鍾左右的時間就做不下去了,不得不直接先讓計算機代勞了。運行環境:WIN7+VS2010
代碼:
1 #include<iostream> 2 #include<string> 3 using namespace std; 4 5 //ack function definition 6 int ack(int m,int n) 7 { 8 if(m == 0) 9 { 10 return n+1; 11 } 12 else if(n == 0) 13 { 14 return ack(m - 1, 1); 15 } 16 else 17 { 18 return ack(m - 1, ack(m, n - 1)); 19 } 20 } 21 22 int main() 23 { 24 cout<<"***********************************"<<endl; 25 cout<<"下面矩陣中第i行第j列的值為ack(i,j)"<<endl; 26 cout<<"i,j的取值從0開始,第一個為ack(0,0)"<<endl; 27 cout<<"***********************************"<<endl; 28 for(int i = 0;i <= 3;i++) 29 { 30 for(int j = 0;j <= 4;j++) 31 { 32 cout<<ack(i,j)<<"\t"; 33 } 34 cout<<endl; 35 } 36 37 return 0; 38 }
運行結果:
由上面的矩陣很容易看出ack(3,3)=61。現在的問題是,面對這樣的一道筆試題,我們應該如何求解?顯然直接遞歸運算量是最大的,因為我們會重復的計算很多值(還記得斐波那契數列的計算?),稍微快一點的方法是直接列出二維表,從頭開始計算,這樣對於計算過的值可以直接使用,不過效率依然不會很高。筆者暫時還沒有發現通項公式或者更快的計算方法,如果有牛人知道,還望不吝賜教!