码迷,mamicode.com
首页 > 其他好文 > 详细

一道腾讯校招试题

时间:2015-05-28 14:11:04      阅读:120      评论:0      收藏:0      [点我收藏+]

标签:c语言

题目:

猴子摘香蕉一次可以摘1个或2个,总共50个,有多少种摘法?


分析:

得到如下规律

技术分享

技术分享


实际上是一个斐波那契数列

以下为我使用的4种解法,分别是递归、迭代、64位整型数、 数组(类似于大数相加)。


代码1: 递归

//其中加入了计时器


#include <iostream>
#include <ctime>
 
using namespace std;
 
int f(int n)
{
    if(n<=0)
        return 0;
    else if(1==n || 2==n)
        return n;
    else 
        return f(n-1)+f(n-2);
     
}
 
int main()
{
    double n;
    clock_t t;
 
    cin>>n;
    cout<<f(n)<<endl;    //我的机子是32位,算不出来,改成long也不行,改成double会丢失精度
    t=clock();
    cout<<t<<endl;    //可以看到,花费的时间非常非常的长。。。。。
    return 0;
}


运行结果1:

//实际上根本算不出来,因为机器年龄大了。。。。哈哈

技术分享

技术分享


只能再找一种更高效的算法 


(⊙o⊙)…等下,它出来了。。。。

技术分享

技术分享


可以看到,溢出了!


代码2: 迭代


#include <iostream>
#include <ctime>
 
using namespace std;
 
int main()
{
    double n,i,a,b,c;
    clock_t t;
    a=1;
    b=2;
    cin>>n;
    if(n<=0)
        cout<<0<<endl;
    else if(1==n || 2==n)
        cout<<n<<endl;
    else
    {
        for(i=2;i<n;i+=2)
        {
            a=a+b;
            b=a+b;
        }
        c=(1==(int)n%2) ? a:b;
        t=clock();
        cout<< c <<endl;
        cout<< t <<endl;
    }
    return 0;
}


运行结果2:

技术分享

技术分享



速度快了很多,但在我用的编译器(VC++6.0)下丢失精度


对了,中间还尝试过使用 __int64

这个东西以前也没用过,临时百度的。试了一下,竟然OK了


代码如下:


#include <iostream>
#include <stdlib.h>
#include <stdio.h>
//#include <stdint.h>
#include <ctime>
 
using namespace std;
 
int main()
{
    int n,i;
    __int64 a,b;
    clock_t t;
    a=1;
    b=2;
    cin>>n;
    if(n<=0)
        cout<<0<<endl;
    else if(1==n || 2==n)   
        cout<<n<<endl;
    else
    {
        for(i=2;i<n;i+=2)
        {
            a=a+b;
            b=a+b;
        }
        if(n%2)
            printf("%I64d\n",a);
        else
            printf("%I64d\n",b);
         
        t=clock();
        cout<< t <<endl;
    }
    return 0;
}


运行结果:

技术分享

技术分享



然后就想,也许用数组来做也行。空间换时间


代码3: 数组(类似于大数相加)


#include <iostream>
#include <cstring>
#include <ctime>
 
using namespace std;
 
int main()
{
 
    int n,i,j,k;
    int a[50][20];
    clock_t t;
 
    memset(a,0,sizeof(a));
 
    a[0][0]=1;
    a[1][0]=2;
 
    for(i=2;i<50;i++)
    {
        for(j=0,k=0;j<20;j++)
        {
            a[i][j]=(a[i-1][j]+a[i-2][j]+k)%10;
            k=(a[i-1][j]+a[i-2][j]+k)/10;
        }
    /*  k=19;
        while(0==a[i][k])
            k--;
        while(k>=0)
        {
            cout<<a[i][k];
            k--;
        }
        cout<<endl;*/
    }
 
 
    cin>>n;
 
    while(n<=0)
        cin>>n;
 
    i=19;
    while(0==a[n-1][i])
        i--;
    while(i>=0)
    {
        cout<<a[n-1][i];
        i--;
    }
    cout<<endl;
 
    t=clock();
    cout<< t <<endl;
 
    return 0;
}



运行结果3:

技术分享

技术分享

结果正确,速度也很快!


代码3的改进版



#include <iostream>
#include <cstring>
#include <ctime>
  
using namespace std;
  
int main()
{
  
    int n,i,j,k,l;
    int a[50][20];
    clock_t t;
  
    memset(a,0,sizeof(a));
  
    a[0][0]=1;
    a[1][0]=2;
  
    l=0;
    for(i=2;i<50;i++)
    {
        for(j=0,k=0;j<=l;j++)
        {
            a[i][j]=(a[i-1][j]+a[i-2][j]+k)%10;
            k=(a[i-1][j]+a[i-2][j]+k)/10;
        }
         
        while(k)                //这样可以避免计算高位为0的数字
        {
            a[i][++l]=k%10;
            k/=10;
        }
    /*  k=19;
        while(0==a[i][k])
            k--;
        while(k>=0)
        {
            cout<<a[i][k];
            k--;
        }
        cout<<endl;*/
    }
  
  
    cin>>n;
  
    while(n<=0)
        cin>>n;
  
    i=19;
    while(0==a[n-1][i])
        i--;
    while(i>=0)
    {
        cout<<a[n-1][i];
        i--;
    }
    cout<<endl;
  
    t=clock();
    cout<< t <<endl;
  
    return 0;
}


附图:

技术分享

技术分享





一道腾讯校招试题

标签:c语言

原文地址:http://blog.csdn.net/u011694809/article/details/46120881

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!