阿里巴巴机试题
题目介绍:
1. 猎人把一对兔子婴儿(一公一母称为一对)放到一个荒岛上,两年之后,它们生下一对小兔,之后开始每年都
会生下一对小兔。生下的小兔又会以同样的方式继续繁殖。
2. 兔子的寿命都是x(x>=3)年,并且生命的最后一年不繁殖。
3. 如果岛上的兔子多于10对,那么猎人会每年在兔子们完成繁殖或者仙逝之后,从岛上带走两对最老的兔子。
请问y年(y>=3)后荒岛上所有的兔子加起来多少岁?(注意, 在条件3执行完之后)
输入: 从命令行输入两行整数,第一行是x,第二行是y
输出: y年后荒岛上所有的兔子岁数的总和
思路:
years作为年限,life作为兔子最大年龄
-
用一个数据保存兔子对年龄的序列,start为队列头,end为队列末尾
-
每一年更新队列:
- 年龄等于life,由于年龄最大的兔子一定是在队伍最前列,故start++
- 每只兔子年龄+1,若达到生育年龄,则队列[++end]置为1
- 更新完队列之后查看是否多余10对
出现问题:
兔子刚生出来应该是一岁还是零岁
若兔子刚生出来是0岁,则2岁时可以生育,
模拟数据为:兔子最大年龄为4岁
年龄 |
兔子序列 |
1 |
1 |
2 |
2 |
3 |
3 1 |
4 |
4 2 |
5 |
5 3 1 |
6 |
5 4 2 |
7 |
5 |
8 |
5 |
9 |
5 |
代码:
#include <iostream>
using namespace std;
int main() {
int years, life;
cin >> life >> years; //输入最大年龄 年限
int Rabbits[1000] = {0};
int start = 0, end = 0;
//Rabbits[end] = 1;
//开始每年的循环,从第一年到第years年
for(int i=1; i<=years; i++) {
int end_tmp = end; //保存下当前的队列末尾
//每年检查图子序列,从开头,到当时的队列末尾
for(int j=start; j<=end_tmp; j++){
Rabbits[j]++; //兔子加一岁
if(Rabbits[j]>life)
start++; //如果有兔子达到最大年龄,在队列最前面减少一对兔子
else if(Rabbits[j]>=3 && Rabbits[j]<life){
end++;
Rabbits[end] = 1; //end增加一个,刷新下一年的队列末尾
}
}
if((end-start+1)>10) {
start +=2;
}
}
int sum = 0;
for(int i=start; i<=end; i++)
sum += 2*Rabbits[i];
cout << sum;
}