设为首页 加入收藏

TOP

2016年4月21百度iOS实习生在线笔试题&编程题
2017-10-13 10:24:15 】 浏览:2348
Tags:2016年 4月 21百度 iOS 实习生 在线 试题 编程

1.一个人上台阶可以一次上1个,2个,或者3个,问这个人上32层的台阶,总共有几种走法?

思路:先建立数学模型,设3步的走 i 次,2步的走 j 次, 1步的走 k 次,上了3*i + 2*j + 1*k = n个台阶.总共走 i + j + k 次, 等于把n个台阶的长度先划分成 i + j + k 个段落, 然后分别填下i个3, j 个2, k个1.这样,当划分成 i + j + k 个段落时, 根据排列组合知识,所有填充方法有 (i + j + k )!/ ( i!*j!*k!) 种,程序中使用GetComb(i,j,k)函数计算此值.
对于i, j, k的确定,我们可以用从大到小划分法, 先划分3的次数,再划分2的次数,剩下的都算做1的次数,具体程序中就是里面的i,j,两重循环.

 1 #include <iostream>
 2 #include  <cstdio>
 3 int Factorial(int n)
 4 {
 5     int ret = n;
 6     if (n<=1)
 7     {
 8         return 1;
 9     }
10     while (n-->1)
11     {
12         ret*=n;
13     }
14     return ret;
15 }
16 
17 //求(i+j+k)!/(i!*j!*k!)
18 
19 int GetComb(int i,int j,int k)
20 {
21     int m = Factorial(i+j+k);
22     int l =  Factorial(i)*Factorial(j)*Factorial(k);
23     return m/l;
24 }
25 
26 
27 int NStepFor123(int n)
28 {
29     int i=0;
30     int j=0;
31     int p;
32     int k;
33     int result=0;
34     for ( i=0; i<=n/3; i++ )
35     {
36         p = n-i*3;
37         for ( j=0; j<=p/2; j++ )
38         {
39             k = p -j*2;
40             //求(i+j+k)!/(i!*j!*k!)
41             result += GetComb(i,j,k);
42         }
43     }  
44     return result;  
45 }
46 int main(int argc, const char * argv[]) {
47     // insert code here...
48     printf("%d",NStepFor123(32));
49     return 0;
50 }

 此题还可以有另一种方法

f(n) = f(n-1)+f(n-2)+f(n-3),特别地f(0)=1;f(1)=1;f(2)=2;
式子的证明为:增加一步共为f(n+1)的时候,把这新的一步算进去后有三种情况,1是这一步仅当一步走为f(n)次,2是这一步配合原来的最后一步作为两步走为f(n-1)次,3是这一步配合前面的两步作三步走为f(n-2);所以式子f(n+1) =f(n)+ f(n-1)+f(n-2),归纳得证。

int f (int k)
{
   int v[3]={1,1,2};
    long index = -1;
    if (k<0)
    {
        return 0;
    }
    
    if (k<3)
    {
        return v[k];
    }
    
    while(k-->2)
    {
        index++;
        index %= 3;
        v[index] = v[0]+v[1]+v[2];
    }
    return v[index];
}
int main(int argc, const char * argv[]) {

    printf("%d",f(32));
    return 0;
}

奇怪的是两个程序运行结果不一致

调试发现前1~13结果一致。由于第二种O(n)所以应是第一种出现问题。

int Factorial(int n) int 不能装下ret所以出错,把它改成 long型就ok了
代码如下
long Factorial(int n)
{
   long ret = n;
    if (n<=1)
    {
        return 1;
    }
    while (n-->1)
    {
        ret*=n;
    }
    return ret;
}


//求(i+j+k)!/(i!*j!*k!)

double GetComb(int i,int j,int k)
{
   double m = Factorial(i+j+k);
    double l =  Factorial(i)*Factorial(j)*Factorial(k);
    return m/l;
}


long NStepFor123(int n)
{
    int i=0;
    int j=0;
    int p;
    int k;
    long result=0;
    for ( i=0; i<=n/3; i++ )
    {
        p = n-i*3;
        for ( j=0; j<=p/2; j++ )
        {
            k = p -j*2;
            //求(i+j+k)!/(i!*j!*k!)
            result += GetComb(i,j,k);
        }
    }
    return result;
}
int main()
{
    
    printf("%ld",NStepFor123(32));
    
    
    return 0;
}
但我们发现在32时仍然不相等,说明阶乘运算得出的ret又大于long的取值了,int64_t仍然不够用,所以要用字符串模拟大数(会很麻烦)
所以建议使用第二种也就是递归的方法解决问题。
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
上一篇objective-c IOS应用更新 下一篇[iOS开发]- 多控制器跳转

最新文章

热门文章

Hot 文章

Python

C 语言

C++基础

大数据基础

linux编程基础

C/C++面试题目