HJ37 统计每个月兔子的总数
- 描述
- 示例
- 解题思路以及代码分析
- 解法1
- 解法2
描述
描述
有一种兔子,从出生后第3个月起每个月都生一只兔子,小兔子长到第三个月后每个月又生一只兔子。
例子:假设一只兔子第3个月出生,那么它第5个月开始会每个月生一只兔子。
一月的时候有一只兔子,假如兔子都不死,问第n个月的兔子总数为多少?
数据范围: 输入满足 1≤n≤31
输入描述:
输入一个int型整数表示第n个月
输出描述:
输出对应的兔子总数
示例
示例1
输入:
3
输出:
2
解题思路以及代码分析
解法1
暴力求解
该题就是兔子第三个月就可以生小兔子,然后小兔子满月了也可以在生小兔子。统计兔子个数。
那就申请一个记录未满月兔子数量的数组,还得申请一个记录未满月兔子第几个月的数组,只要满足2个月了,那么就是第三个月可以生小兔子的兔子,因此还得申请一个变量记录可以生兔子的兔子,最后把可以生兔子的兔子和未满月的兔子都加起来就可以了。说着有点麻烦,那我们画图分析一下吧!
第一个月
//1月份
NFMRabbit[1]=1;
RSubscript[1]=1;
int FistrNoFMRT=1;
int FinalNoFMRT=1;
第二个月
每个月先检查是否有可以生兔子的兔子,有的话就生,然后给没满月的兔子都加一个月,看看有没有满月的兔。有的话这个兔子就是一个可以生兔子的兔子。
//从2月开始记录
int i=0;
for(i=2;i<=Month;i++)
{
//产兔
int j=FMRabbit;
while(j--)
{
NFMRabbit[++FinalNoFMRT]=1;
}
//检查是否有资格可以下个月生兔子
if(FistrNoFMRT <= FinalNoFMRT)
{
int k=FistrNoFMRT;
while(k<=FinalNoFMRT)
{
RSubscript[k]+=1;
if(RSubscript[k] == 2)
{
FMRabbit+=1;
FistrNoFMRT++;
}
k++;
}
}
}
第三个月
第四个月
第五个月
假如Month=5;那么把未满月的和满月的兔子加起来就是最终答案
//统计兔子数量
int m=0;
int NoFMRsum=0;
for(int m=FistrNoFMRT;m<=FinalNoFMRT;m++)
{
NoFMRsum+=1;
}
printf("%d\n",NoFMRsum+FMRabbit);
int main() {
int Month=0;
scanf("%d",&Month);
int FMRabbit=0;
int* NFMRabbit=(int*)calloc(10000000,sizeof(int));
int* RSubscript=(int*)calloc(10000000,sizeof(int));
//1月份
NFMRabbit[1]=1;
RSubscript[1]=1;
int FistrNoFMRT=1;
int FinalNoFMRT=1;
//从2月开始记录
int i=0;
for(i=2;i<=Month;i++)
{
//产兔
int j=FMRabbit;
while(j--)
{
NFMRabbit[++FinalNoFMRT]=1;
}
//检查是否有资格可以下个月生兔子
if(FistrNoFMRT <= FinalNoFMRT)
{
int k=FistrNoFMRT;
while(k<=FinalNoFMRT)
{
RSubscript[k]+=1;
if(RSubscript[k] == 2)
{
FMRabbit+=1;
FistrNoFMRT++;
}
k++;
}
}
}
//统计兔子数量
int m=0;
int NoFMRsum=0;
for(int m=FistrNoFMRT;m<=FinalNoFMRT;m++)
{
NoFMRsum+=1;
}
printf("%d\n",NoFMRsum+FMRabbit);
return 0;
}
解法2
这个题细心的同学可以发现,这其实是一个斐波那契数列。第 n 个月的兔子数量实际上就是第 n-1 个斐波那契数。从第三个数开始,每个数都是第N-1项和第N-2项的和。
int main() {
int n=0;
while(scanf("%d",&n) != EOF)
{
if(n<3)
{
printf("%d",1);
}
else
{
int num1=1,num2=1,sum=0;
for(int i=3;i<=n;i++)
{
sum=num1+num2;
num1=num2;
num2=sum;
}
printf("%d",sum);
}
}
return 0;
}