阿里编程测验题目交流
题目描述:
- 猎人把一对兔子婴儿(一公一母称为一对)放到一个荒岛上,两年之后,它们生下一对小兔,之后开始每年都会生下一对小兔。生下的小兔又会以同样的方式继续繁殖。
- 兔子的寿命都是x(x>=3)年,并且生命的最后一年不繁殖。
- 如果岛上的兔子多于10对,那么猎人会每年在兔子们完成繁殖或者仙逝之后,从岛上带走两对最老的兔子。
请问y年(y>=3)后荒岛上所有的兔子加起来多少岁?
输入: 从命令行输入两行整数,第一行是x,第二行是y
输出: y年后荒岛上所有的兔子岁数的总和
我的思路:维护一个队列or链表,每年新加入的兔子从队尾加入,死掉的兔子总是从队首去除。队列长度<=x。时间复杂度O(x*y),空间复杂度O(x)。
我的代码:
#include <iostream>
#include <list>
using namespace std;
struct Rabbit
{
long long age;
long long num;
Rabbit(long long age, long long num):age(age), num(num){}
};
int main()
{
long long x, y;
while(cin>>x>>y)
{
list<Rabbit> l;
l.push_back(Rabbit(0, 1));
long long sumRabbitNum = 1;
for(int year = 1; year <= y; ++year)
{
list<Rabbit>::iterator it;
for(it = l.begin(); it != l.end(); it++)
{
it->age++;
}
it = l.begin();
while(it != l.end())
{
if(it->age >= x)
{
sumRabbitNum -= it->num;
l.pop_front();
it = l.begin();
}
else break;
}
long long newRabbitCnt = 0;
for(it = l.begin(); it != l.end(); it++)
{
if(it->age >= 2) newRabbitCnt += it->num;
}
if(newRabbitCnt) l.push_back(Rabbit(0, newRabbitCnt));
sumRabbitNum += newRabbitCnt;
if(sumRabbitNum > 10)
{
sumRabbitNum -= 2;
list<Rabbit>::iterator it = l.begin();
if(it->num > 2) it->num -= 2;
else if(it->num == 2) l.pop_front();
else
{
l.pop_front();
it = l.begin();
if(it->num > 1) it->num--;
else
{
l.pop_front();
}
}
}
}
long long sumRabbitAge = 0;
for(list<Rabbit>::iterator it = l.begin(); it != l.end(); it++)
{
sumRabbitAge += it->age * it->num;
}
sumRabbitAge <<= 1;
cout<<sumRabbitAge<<endl;
}
return 0;
} 时间复杂度可以优化到O(y)。
优化思路:
1.把Rabbit中的age字段改为出生年份,这样就不用遍历队列去更新age了;
2.求年龄>=2的兔子数,可以用总的兔子数减去队尾一个节点的兔子数。
优化后的代码:
#include <iostream>
#include <list>
using namespace std;
struct Rabbit
{
long long birth;
long long num;
Rabbit(long long birth, long long num) : birth(birth), num(num){}
};
int main()
{
int x, y;
while(cin>>x>>y)
{
list<Rabbit> q;
q.push_back(Rabbit(0, 1));
long long sumRabbit = 1;
for(int i = 1; i <= y; ++i)
{
auto it = q.begin();
if(it != q.end() && i - it->birth >= x)
{
sumRabbit -= it->num;
q.pop_front();
}
long long sumNewRabbit = sumRabbit;
auto rit = q.rbegin();
if(rit != q.rend() && i-rit->birth < 2) sumNewRabbit -= rit->num;
if(sumNewRabbit > 0) q.push_back(Rabbit(i, sumNewRabbit));
sumRabbit += sumNewRabbit;
if(sumRabbit > 10)
{
sumRabbit -= 2;
it = q.begin();
if(it->num > 2) it->num -= 2;
else if(it->num == 2) q.pop_front();
else
{
q.pop_front();
it = q.begin();
if(it->num > 1) it->num--;
else q.pop_front();
}
}
}
long long sumAge = 0;
for(auto it = q.begin(); it != q.end(); it++) sumAge += (y - it->birth) * it->num;
sumAge <<= 1;
cout<<sumAge<<endl;
}
return 0;
}#阿里巴巴##C++工程师#

