阿里编程测验题目交流

题目描述:

  1. 猎人把一对兔子婴儿(一公一母称为一对)放到一个荒岛上,两年之后,它们生下一对小兔,之后开始每年都会生下一对小兔。生下的小兔又会以同样的方式继续繁殖。
  2. 兔子的寿命都是x(x>=3)年,并且生命的最后一年不繁殖。
  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++工程师#
全部评论
#include <iostream> #include <vector> using namespace std; int solve(int x, int y) { vector<int> baby(y + 1, 0); baby[0] = 1; int rabb = 1; int die = 0; for (int i = 1; i <= y; ++i) { if (i >= x) rabb -= baby[die++]; baby[i] = rabb - baby[i - 1]; rabb += baby[i]; if (rabb > 10) { rabb -= 2; int idx = die; while (baby[idx] == 0) ++idx; if (baby[idx] == 1) { baby[idx++] = 0; while (baby[idx] == 0) ++idx; --baby[idx]; } else { baby[idx] -= 2; } } } int ans = 0; int cur = y >= x ? (y - x + 1) : 0; for (; cur <= y; ++cur) ans += (y - cur) * baby[cur]; return 2 * ans; } int main() { int x, y; cin >> x >> y; cout << solve(x, y); return 0; }
点赞 回复 分享
发布于 2017-08-16 12:39
/* 猎人把一对兔子婴儿(一公一母称为一对)放到一个荒岛上,两年之后,它们生下一对小兔, 之后开始每年都会生下一对小兔。生下的小兔又会以同样的方式继续繁殖。 兔子的寿命都是 x(x >= 3)年,并且生命的最后一年不繁殖。 如果岛上的兔子多于10对,那么猎人会每年在 兔子们完成繁殖或者仙逝之后,从岛上带走两对最老的兔子。请问y年(y >= 3)后荒岛上所有 的兔子加起来多少岁 ? 输入 : 从命令行输入两行整数,第一行是x,第二行是y输出 : y年 后荒岛上所有的兔子岁数的总和 */ //看题主题目做得,具体对不对不知道 #include <iostream> #include <vector> using namespace std; void getresult(int x, int y){ vector<int> v; v.push_back(0); //v.push_back(0); int num = 1; int age = 0; while (y--){ for (int i = 0; i < v.size(); i++){ if (v[i] >= 0) v[i]++;//活着的和寿命已满的加一岁。 } int len = v.size(); for (int i = 0; i < len; i++){ if (v[i] == x){ v[i] = -2; num--; //-2代表这一年没有生育能力 } //else if (v[i] == x - 1); else if (v[i] >= 2){ //大于等于两岁的生一对,存在数组中 v.push_back(0); num++; } } //如果兔子数量超过10只带走最老的或者死掉的最老的。 if (num > 10){ num--; int j = 0; while (v[j] == -2) j++;//-4代表被带走的。 v[j] = -2; } } for (int i = 0; i < v.size(); i++){ if (v[i] > 0){ age += v[i];//活着的岁数相加 } } cout << 2*age << endl;//一对是两只,所以乘以2 } int main1(){ int x; int y; cin >> x; cin >> y; getresult(x, y); return 0; }
点赞 回复 分享
发布于 2017-08-17 00:39
楼主真大神,这题我做了,通过率20
点赞 回复 分享
发布于 2017-08-16 11:28
在线编程一定要3天之内做完,过期就作废了,邮件中居然没有告知我,哎~
点赞 回复 分享
发布于 2017-08-16 21:04
题目描述: 1. 猎人把一对兔子婴儿(一公一母称为一对)放到一个荒岛上,两年之后,它们生下一对小兔,之后开始每年都会生下一对小兔。生下的小兔又会以同样的方式继续繁殖。  2. 兔子的寿命都是x(x>=3)年,并且生命的最后一年不繁殖。  3. 如果岛上的兔子多于10对,那么猎人会每年在兔子们完成繁殖或者仙逝之后,从岛上带走两对最老的兔子。  请问y年(y>=3)后荒岛上所有的兔子加起来多少岁?(注意, 在条件3执行完之后) 输入: 从命令行输入两行整数,第一行是x,第二行是y  输出: y年后荒岛上所有的兔子岁数的总和 输入:  x //兔子的寿命  y //若干年以后  输出:  n //所有兔子的年龄之和  思路: 结构体:兔子年龄和最大年龄 遍历Y年{ 每只年龄在2-(maxAge-1)之间的兔子都生只兔子(两只生两只,就是一只生一只); 年龄>=maxAge的兔子仙逝; 若岛上只数>20只,则带走年龄最大的4只兔子。 } 累加岛上兔子年龄。 */ #include<iostream>   #include <vector>   #include <algorithm>   using namespace std; struct Rab { int age; int maxAge; }; void AgeAdd(vector<Rab> &sum) { vector<Rab>::iterator it; for (it = sum.begin(); it != sum.end(); it++) { it->age++;//年龄加1 } } void Dead(vector<Rab> &sum) { vector<Rab>::iterator it; for (it = sum.begin(); it != sum.end();) { if (it->age >= it->maxAge)//达到最大年龄,仙逝 it = sum.erase(it); else it++; } } void Birth(vector<Rab> &sum, int x) { vector<Rab>Temp; vector<Rab>::iterator it; for (it = sum.begin(); it != sum.end(); it++) {//每一对兔子每年生一对兔子,相当于每一年每一只兔子生一只兔子 if (it->age >= 2 && it->age < it->maxAge)//年龄在两岁到最大岁减一之间可以生小兔 { Rab newborth = { 0, x }; Temp.push_back(newborth); } } for (vector <Rab>::iterator iter = Temp.begin(); iter != Temp.end(); iter++){ sum.push_back((*iter)); } //以下是上述for循环的简略写法,参考auto在容器中的用法 //for (auto x : Temp) // sum.push_back(x); } int main() { int x, y;//寿命和年数 cin >> x >> y; //Rab R1 = { 0, x };//公 Rab R2 = { 0, x };//母 vector<Rab> sum; sum.push_back(R1); //sum.push_back(R2); for (int i = 0; i < y; i++) {//遍历年数,一共y年 AgeAdd(sum);//年龄增长 Dead(sum);//兔子仙逝 Birth(sum, x);//兔子出生 if (sum.size() > 20) {//兔子数多于十对,带走两对最老的 sum.erase(sum.begin()); sum.erase(sum.begin()); sum.erase(sum.begin()); sum.erase(sum.begin()); } } int num = 0; for (vector <Rab>::iterator iter = sum.begin(); iter != sum.end(); iter++){ num = num + (*iter).age; } //以下是上述for循环的简略写法,参考auto在容器中的用法 //for (auto x : sum) //num = num + x.age; cout << num << endl; }
点赞 回复 分享
发布于 2017-08-17 17:28
/* 阿里巴巴2018年秋季招聘研发工程师编程测试题 1. 猎人把一对兔子婴儿(一公一母称为一对)放到一个荒岛上,两年之后,它们生下一对小兔,之后开始每年都会生下一对小兔。生下的小兔又会以同样的方式继续繁殖。 2. 兔子的寿命都是x(x>=3)年,并且生命的最后一年不繁殖。 3. 如果岛上的兔子多于10对,那么猎人会每年在兔子们完成繁殖或者仙逝之后,从岛上带走两对最老的兔子。 请问y年(y>=3)后荒岛上所有的兔子加起来多少岁?(注意, 在条件3执行完之后) 输入: 从命令行输入两行整数,第一行是x,第二行是y 输出: y年后荒岛上所有的兔子岁数的总和 */ #include <iostream> #include <algorithm> #include <string> #include<cmath> #include<vector> #include<map> #include<cctype> #include<queue> #include<stack> using namespace std; void jian1(vector<int> &v, int x) { int new_count = 0; int dead_count = 0; for (int i = 0; i < v.size(); i++) { v[i]--; if (v[i] == 0) { dead_count++; continue; } if (x - v[i] >= 2) { new_count++; } } v.assign(v.begin() + dead_count, v.end()); for (int i = 0; i < new_count; i++) { v.push_back(x); } if (v.size() > 10) { v.assign(v.begin() + 2, v.end()); } } int main() { //freopen("input.txt", "r", stdin); int x, y; while (cin >> x >> y) { vector<int> v; v.push_back(x); for (int i = 1; i <= y; i++) jian1(v, x); int result = 0; for (int i = 0; i < v.size(); i++) { //cout <<x- v[i] << ' '; result += (x - v[i]); } //cout << endl; cout << result * 2 << endl; } }
点赞 回复 分享
发布于 2017-08-17 22:52
第三个条件,是应该在兔子繁殖之后,猎人拿走最老的兔子;还是在死亡之后拿走兔子。这两种情况是不一样的。兔子总数大于10,是第年繁殖和死亡之前的值吧。
点赞 回复 分享
发布于 2017-08-18 17:11
有人有测试数据么?
点赞 回复 分享
发布于 2017-08-21 22:53
long solve(int x,int y) { int year[1000] = { 0 }; int num[1000] = { 0 }; year[0] = 1; long result(0); for (int i = 1;i <= y;i++) { int sum=0; for (int j = i;j > 0;j--) year[j] = year[j - 1]; year[0] = 0; if (i >= 2) for (int j = x - 1;j > 1;j--) year[0] += year[j]; year[x] = 0; if (i < x) for (int j = i;j >= 0;j--) sum += year[i]; int jj=x-1; int sub = 2; if (sum>10) while ((jj > 0) && (sub)) { if (year[jj] >= 2) year[jj] -= sub; if (year[jj] == 1) { year[jj] -= sub; sub--; } jj--; } } for (int i = 0;i < x;i++) result += (year[i] * i); return result*2; } int main() { int x, y; cin >> x >> y; cout << solve(x, y); return 0; }
点赞 回复 分享
发布于 2017-08-25 01:50

相关推荐

小红书 后端选手 n*16*1.18+签字费期权
点赞 评论 收藏
分享
10-05 11:11
海南大学 Java
投票
理想江南137:感觉挺真诚的 感觉可以试一试
点赞 评论 收藏
分享
评论
点赞
40
分享
牛客网
牛客企业服务