2017阿里笔试 用模板库中的vector解决笔试中的兔子繁殖问题

来源:互联网 发布:电子白板软件下载 编辑:程序博客网 时间:2024/06/04 20:03

问题介绍:

1. 猎人把一对兔子婴儿(一公一母称为一对)放到一个荒岛上,两年之后,它们生下一对小兔,之后开始每年都
会生下一对小兔。生下的小兔又会以同样的方式继续繁殖。
2. 兔子的寿命都是x(x>=3)年,并且生命的最后一年不繁殖。
3. 如果岛上的兔子多于10对,那么猎人会每年在兔子们完成繁殖或者仙逝之后,从岛上带走两对最老的兔子。
请问y年(y>=3)后荒岛上所有的兔子加起来多少岁?(注意, 在条件3执行完之后)

输入: 从命令行输入两行整数,第一行是x,第二行是y

输出: y年后荒岛上所有的兔子岁数的总和

思路:

一、定义一个有一个元素的整型矢量,元素值为0。矢量内存的是年龄,元素个数为兔子对数

二、更新矢量(每一年检查更新一次):

更新原则:

1、年龄是否等于n:是,删除此对

2、年龄是否大于等于2:是,在矢量末尾加入一0元素(新生兔子)

3、是否多于10对:是,删除矢量前面两组数据(年龄最大的两对)

三、计算兔子总年龄

矢量元素和*2


部分数据如下表:

程序如下:

注意:在测试程序通过率时将system("pause");去掉,否则没分!!!

#include<iostream>#include<vector>using namespace std;int main(){int x, y,age_sum=0;vector<int>ages(1);ages[0] = 0;cout << "输入兔子寿命x和经过的年数y(空格或者换行为间隔符)" << endl;cin >> x >> y;if (x < 3 || y<3){cout << "Please input a good data : x>=3 and y>=3 !" << endl;return 0;}for (int i = 1; i <= y; i++){int adder = 0;for (auto p = ages.begin(); p!=ages.end(); )//update ages and pair{(*p)++;//age+1if (*p == x)//年末判断,如 果到了寿命,直接删除{p = ages.erase(p);continue;}if (*p >= 2)//*p < x 一直为真,不需要考虑!{ages.push_back(-1);//add a pair//放在里面更新模板,需要考虑迭代器更新问题p = ages.begin();//更新迭代器位置:添加元素后,模板位置发生变化,迭代器位置也要相应改变p += adder;}adder++;p++;}if (ages.size() > 10)//>10,delete a pair(the first one)//年末处理for (int i = 0; i < 2; i++)//取走年龄最大的两对rabbitsages.erase(ages.begin());}for (int i : ages)//compute age sumage_sum += i*2;cout << "age_sum of all rabbits is:" << age_sum << endl;system("pause");return true;}


程序中使用的是向量vector编写的,如果用双端队列deque会更好,因为处理的数据都是在两端操作——头节点删除和尾节点添加。使用deque可以避免vector头结点删除时后面所有节点前移一个位置的累赘操作!

程序更改:1、包含deque头文件   #include<deque> 2、vector<int>ages(1); 改为:deque<int>ages(1);  

其余部分不变

注意事项:

迭代器的更新:
1、添加元素工作:
push_back()操作后矢量大小发生变化,内存地址发生变化。所以添加完元素后需要对迭代器重新定义位置信息。程序中的adder就是为了记录当前迭代器p的位置的。
2、删除当前元素:
erase()操作后,迭代器自动将后面的所有元素向前移动一个,末尾位置更新,但迭代器所指向的位置不变,从而达到指向下一个位置的效果。如果此处使用for循环遍历矢量元素,需注意for(i;i<b;i++)循环中第三个参数和删除中的自动前移,迭代器定位下一元素的操作重复,会跳过下本应指向的下一位置!
(详细内容请参考:http://www.cnblogs.com/newbeeyu/p/6883122.html)
for的执行过程如下
(C Primer Plus,第六版 P151)