1.斐波那契凤尾
链接:https://www.nowcoder.com/questionTerminal/c0a4b917a15f40a49ca10532ab9019fb
来源:牛客网
题目描述:
NowCoder号称自己已经记住了1-100000之间所有的斐波那契数。
为了考验他,我们随便出一个数n,让他说出第n个斐波那契数。当然,斐波那契数会大。
因此,如果第n个斐波那契数不到6位,则说出该数;否则只说出最后6位。
输入描述:
输入有多组数据。
每组数据一行,包含一个整数n (1≤n≤100000)。
输出描述:
对应每一组输入,输出第n个斐波那契数的最后6位。
示例:
输入
1
2
3
4
100000
输出
1
2
3
5
537501
题目分析:
- 斐波那契数增长速度很快,当超过25项时,斐波那契数超过六位数。
- 输入数据 n 的范围是 1≤n≤100000,所以随着n的增大,很难计算或保存斐波那契数。
- 在这里计算的时候,只保留每个斐波那契数的后六位,这样用 int 类型就可以保存前1000000项斐波那契数,具体操作是与1000000进行求余运算。
- 斐波那契数是由前两项的和计算得出,因此,计算前两项后六位的和再也可以保证结果是该项斐波那契数的后六位。
- 输出时,原本斐波那契数超过六位,但求余运算后不满六位,输出时可以在前面补0。
代码示例:
#include <iostream>
#include <vector>
#include <iomanip>
using namespace std;
int main()
{
vector<int> v(1000002);
v[0]=1;
v[1]=1;
for(int i=2;i<=1000000;++i)
{
v[i]=v[i-1]+v[i-2];
v[i]%=1000000;
}
int n;
while(cin>>n)
{
if(n>=25)
{
cout<<setfill('0')<<setw(6)<<v[n]<<endl;
}
else
cout<<v[n]<<endl;
}
return 0;
}
2.养兔子
链接:https://www.nowcoder.com/questionTerminal/71d3849a19f04a1591c415964ac148f1?toCommentId=51150
来源:牛客网
题目描述:
一只成熟的兔子每天能产下一胎兔子。每只小兔子的成熟期是一天。 某人领养了一只小兔子,请问第N天以后,他将会得到多少只兔子。
输入描述:
测试数据包括多组,每组一行,为整数n(1≤n≤90)。
输出描述:
对应输出第n天有几只兔子(假设没有兔子死亡现象)。
示例
输入
1
2
输出
1
2
题目分析:
- 通过列举前几项,可以看到此题是明显的斐波那契数列应用问题,题目要求输出指定项的斐波那契数。
- 给定输入范围是 n(1≤n≤90),所以在计算过程中要防止数据溢出。
代码示例:
#include <iostream>
#include <vector>
using namespace std;
int main()
{
vector<int64_t> v(91);
v[0]=1;
v[1]=1;
for(int i=2;i<91;++i)
{
v[i]=v[i-1]+v[i-2];
}
int n=0;
while(cin>>n)
{
cout<<v[n]<<endl;
}
return 0;
}
3.客似云来
链接:https://www.nowcoder.com/questionTerminal/3549ff22ae2c4da4890e9ad0ccb6150d
来源:牛客网
题目描述:
NowCoder开了一家早餐店,这家店的客人都有个奇怪的癖好:他们只要来这家店吃过一次早餐,就会每天都过来;并且,所有人在这家店吃了两天早餐后,接下来每天都会带一位新朋友一起来品尝。于是,这家店的客人从最初一个人发展成浩浩荡荡成百上千人:1、1、2、3、5……现在,NowCoder想请你帮忙统计一下,某一段时间范围那他总共卖出多少份早餐(假设每位客人只吃一份早餐)。
输入描述:
测试数据包括多组。
每组数据包含两个整数from和to(1≤from≤to≤80),分别代表开店的第from天和第to天。
输出描述:
对应每一组输入,输出从from到to这些天里(包含from和to两天),需要做多少份早餐。
题目分析:
- 通过列举前几项,可以看到此题是明显的斐波那契数列应用问题,题目要求对斐波那契数列指定区间项求和。
- 给定输入范围是 1≤from≤to≤80,所以在计算过程中要选择合适的数据类型,防止数据溢出。
- 波那契数列的的前n项和是有一个很有意思的公式,这里只用结果。
- 斐波那契数列的前n项和,就是第n+2项的值减1。所以,要求第n项到第m项的和,那么只要求出前m项的和,减去前n - 1项的和,就能得到结果。例如要求第3项到第5项的和,我们就只需要用前5项的和减去前2项的和,而公式中的减一在这个过程中抵消掉了,也就是结果直接就是第7项的值减去第4项的值,这样我们在操作的时候就更简单了。就数值而言,第7项是13,第4项是3,差值是10,而2+3+5也是10,结果是正确的。
代码示例:
循环求和:
#include <iostream>
#include <vector>
using namespace std;
int main()
{
vector<uint64_t> v(80);
v[0]=1;
v[1]=1;
for(int i=2;i<80;++i)
{
v[i]=v[i-1]+v[i-2];
}
int from,to;
while(cin>>from>>to)
{
uint64_t sum=0;
for(int i=from;i<=to;++i)
{
sum+=v[i-1];
}
cout<<sum<<endl;
}
return 0;
}
用前n项和公式求和
#include <iostream>
#include <vector>
using namespace std;
int main()
{
vector<uint64_t> v(82);
v[0]=1;
v[1]=1;
for(int i=2;i<82;++i)
{
v[i]=v[i-1]+v[i-2];
}
int from,to;
while(cin>>from>>to)
{
uint64_t sum=0;
sum=v[to+1]-v[from];
cout<<sum<<endl;
}
return 0;
}