您的位置:首页 > 编程语言 > C语言/C++

一道腾讯校招试题

2015-05-28 13:07 176 查看
题目:

猴子摘香蕉一次可以摘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语言