题目描述:
该题目来自前两天腾讯实习生的招聘笔试,题目给出如下的递归函数,求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。现在的问题是,面对这样的一道笔试题,我们应该如何求解?显然直接递归运算量是最大的,因为我们会重复的计算很多值(还记得斐波那契数列的计算?),稍微快一点的方法是直接列出二维表,从头开始计算,这样对于计算过的值可以直接使用,不过效率依然不会很高。笔者暂时还没有发现通项公式或者更快的计算方法,如果有牛人知道,还望不吝赐教!