一个阿里笔试题

版权声明:本文为博主原创文章,转载请联系博主。 https://blog.csdn.net/u013453604/article/details/51205169

N个小孩手中拿着一个随机数排成一排,现在给小孩子发饼干,每个小孩子都至少能分到一个饼干,手中拿着的数字大的小朋友的饼干数要大于隔壁小朋友的。请编写程序计算一下:你至少要发多少个饼干。同时针对你写的这段程序给出测试方案。

思路:一次遍历碰到上升序列直接递增分配饼干,碰到下降序列记下下降起始位置和长度,等到下降序列结束再逆向分配饼干

/******
*N个小孩手中拿着一个随机数排成一排,现在给小孩子发饼干,
*每个小孩子都至少能分到一个饼干,手中拿着的数字大的小朋友的饼干数要大于隔壁小朋友的。
*请编写程序计算一下:你至少要发多少个饼干。同时针对你写的这段程序给出测试方案。
******/

#include <iostream>
#include <vector>
#include <cstdlib>
#include <conio.h>
#include <time.h>
using namespace std;

int Mincookie(int N) {
    vector<int> child(N), cookie(N);
    //生成小孩的随机数
    int tmp;
    srand((unsigned)time(NULL));
    for (int i = 0; i<N; i++) {     
        tmp = rand() % 99 + 1;
        child[i]=tmp;
    }
    // int tmp[5] = { 3,3,3,3,3 };//测试数据{ 5,7,6,5,4 }{6,4,4,5,6}{6,6,12,12,13}{2,4,3,5,2}{3,3,3,3,3}{}
    // for (int i = 0; i<N; i++) {
    //  child[i] = tmp[i];
    // }

     int cookie_temp=0,begin_flag=-1,length=0;
     cookie[0] = 1;
     for (int i = 1; i < N; i++) {
         if (child[i - 1] < child[i]) { 
         //上升
             if (begin_flag != -1) {
             //如果i-1处于不上升序列末端,即该位置小孩拿到的数是一个极小值
                 cookie[i - 1] = 1;
                 cookie[i] = cookie[i - 1] + 1;
                 //开始从i-1到begin_flag+1开始为length个孩子分配饼干
                 for (int j = i - 2; j > begin_flag; j--) {
                     cookie[j] = child[j]==child[j+1]?cookie[j+1]:cookie[j + 1] + 1;
                 }
                 cookie_temp= child[begin_flag] == child[begin_flag + 1] ? cookie[begin_flag + 1] : cookie[begin_flag + 1] + 1;
                 cookie[begin_flag] = cookie[begin_flag]>cookie_temp ? cookie[begin_flag] : cookie_temp;
                 length = 0;
                 begin_flag = -1;
             }
             else if (begin_flag == -1) {
             //如果i与i-1都处于不下降序列中
                 cookie[i] = cookie[i - 1] + 1;
             }
         }
         else if (child[i - 1] == child[i]) {
         //相等
             cookie[i] = cookie[i - 1];
             length = begin_flag == -1 ? 0 : length + 1;//如果不上升序列中出现相等的情况也要使length自增
         }
         else if (child[i - 1] > child[i]) {
         //下降
             if (begin_flag == -1) {
             //i-1处是一个极大值点
                 begin_flag = i - 1;
                 length = 0;
             }
             else if (begin_flag != -1) {
                 length++;
             }
         }
     }
     if (begin_flag != -1) {
     //如果最后一轮还有不上升序列未处理      
         for (int j = N-1; j > begin_flag; j--) {
             if (j == N - 1) {
                 cookie[N - 1] = 1;
             }
             else {
                 cookie[j] = child[j] == child[j + 1] ? cookie[j + 1] : cookie[j + 1] + 1;
             }           
         }
         cookie_temp = child[begin_flag] == child[begin_flag + 1] ? cookie[begin_flag + 1] : cookie[begin_flag + 1] + 1;
         cookie[begin_flag] = cookie[begin_flag]>cookie_temp ? cookie[begin_flag] : cookie_temp;
         length = 0;
         begin_flag = -1;
     }
     //统计饼干数
    int count = 0;
    for (int i = 0; i<N; i++) {
        count += cookie[i];
    }
    //打印输出
    cout << "随机数:";
    for (int i = 0; i<N; i++) {
        cout << child[i] << "  ";
    }
    cout << endl;
    cout << "饼干数:";
    for (int i = 0; i<N; i++) {
        cout << cookie[i] << "   ";
    }
    cout << endl;
    return count;
}

int main(int argc, char const *argv[])
{
    int count = 0, N = 5;

    count = Mincookie(N);
    cout << "最小饼干数:" << count << endl;

    //_getch();
    return 0;
} 

以下思路虽然直观,但是会让问题复杂化,需要考虑的情况太细,而且正如评论里@汲水的鱼 所提出的,在首尾以及出现相等的情况下会出问题,故以下代码作废,更新的解决方案在上面

/******
*N个小孩手中拿着一个随机数排成一排,现在给小孩子发饼干,
*每个小孩子都至少能分到一个饼干,手中拿着的数字大的小朋友的饼干数要大于隔壁小朋友的。
*请编写程序计算一下:你至少要发多少个饼干。同时针对你写的这段程序给出测试方案。
******/

#include <iostream>
#include <vector>
#include <cstdlib>
#include <conio.h>
#include <time.h>
using namespace std;

int Mincookie(int N) {
    vector<int> child(N), flag_num(N), cookie(N);
    //child是孩子拿的随机数,孩子拿着随机数排成一排,可以看做一条波形曲线
    //flag_num是标记,随机数波谷标记为-1,波峰标记为1,cookie是每个孩子分到的最小饼干数

    //生成随机数,同时记录波峰波谷
    int tmp;
    srand((unsigned)time(NULL));
    for (int i = 0; i<N; i++) {     
        tmp = rand() % 99 + 1;
        child[i]=tmp;
        if (i>1&&i<N) {
            if (child[i - 2]>child[i - 1] && child[i - 1]<child[i]) {
                flag_num[i - 1] = -1;//该孩子的随机数是局部极小值
            }
            else if (child[i - 1]>child[i - 2] && child[i - 1]>child[i]) {
                flag_num[i - 1] = 1;//该孩子的随机数是局部极大值
            }
        }
    }

    //从波谷开始分饼干,flag_cookie是已经被分过饼干的孩子数,j是计步器
    int j = 1, flag_cookie = 0;
    while (flag_cookie <= N) {
        for (int i = 0; i<N; i++) {
            if (i == 0 && child[0] <= child[1]) {
            //情况一、开头不下降
                cookie[0] = 1;//分一块饼干
                flag_cookie++;
                //向右分饼干
                j = 1;
                while (flag_num[i + j] == 0) {
                    //
                    if (child[i + j] > child[i + j - 1]) {
                        cookie[i + j] = j + 1;
                        flag_cookie++;
                        j++;
                        if (i + j >= N) {
                            break;
                        }
                    }
                    else if (child[i + j] = child[i + j - 1]) {
                    //考虑不下降序列中相等的情况
                        cookie[i + j] = cookie[i + j - 1 ];
                        flag_cookie++;      
                        j++;
                        if (i + j >= N) {
                            break;
                        }
                    }                   
                }
                if (i + j < N) {//防止下标右边越界
                    if (flag_num[i + j] == 1) {
                        cookie[i + j] = cookie[i + j]>j + 1 ? cookie[i + j] : j + 1;//波峰处要比较从相邻两个波谷传过来的饼干数取较大者
                        flag_cookie= cookie[i + j]==0? flag_cookie+1: flag_cookie;//如果已经分配过饼干flag_cookie就不再计数
                    }
                }
            }               
            if (flag_num[i] == -1||(i==N-1&&child[N-1]<child[i-2])) {
            //情况二、从波谷向两边分饼干
                cookie[i] = 1;//波谷分一块饼干
                flag_cookie++;
                //向左分饼干
                j = 1;
                while (flag_num[i - j] == 0) {
                    if (child[i - j] > child[i - j + 1]) {
                        cookie[i - j] = cookie[i - j + 1]+1;
                        flag_cookie++;
                        j++;
                        if (i - j < 0) {
                            break;
                        }
                    }
                    else if (child[i - j] == child[i - j + 1]) {
                        cookie[i - j] = cookie[i - j + 1 ];
                        flag_cookie++;
                        j++;
                        if (i - j < 0) {
                            break;
                        }
                    }
                }
                if(i - j > 0) {//防止下标超出左边界
                    if (flag_num[i - j] == 1) {
                        cookie[i - j] = cookie[i - j]>(j + 1) ? cookie[i - j] : (j + 1);
                        flag_cookie = cookie[i - j] == 0 ? flag_cookie + 1 : flag_cookie;
                    }
                }

                //向右分饼干
                if (i < N - 1) {
                    j = 1;
                    while (flag_num[i + j] == 0) {
                        if (child[i + j] > child[i + j - 1]) {
                            cookie[i + j] = cookie[i + j - 1] + 1;
                            flag_cookie++;
                            j++;
                            if (i + j >= N) {
                                break;
                            }
                        }
                        else if (child[i + j] = child[i + j - 1]) {
                            cookie[i + j] = cookie[i + j - 1];
                            flag_cookie++;
                            j++;
                            if (i + j >= N) {
                                break;
                            }
                        }

                    }
                    if (i + j < N) {
                        if (flag_num[i + j] == 1) {
                            cookie[i + j] = cookie[i + j]>j + 1 ? cookie[i + j] : j + 1;
                            flag_cookie = cookie[i + j] == 0 ? flag_cookie + 1 : flag_cookie;
                        }
                    }
                }               
            }
        }

    }//end while

     //统计饼干数
    int count = 0;
    for (int i = 0; i<N; i++) {
        count += cookie[i];
    }

    //打印输出
    cout << "随机数:";
    for (int i = 0; i<N; i++) {
        cout << child[i] << "  ";
    }
    cout << endl;
    cout << "饼干数:";
    for (int i = 0; i<N; i++) {
        cout << cookie[i] << "   " ;
    }
    cout << endl;
    return count;
}

int main(int argc, char const *argv[])
{
    int count = 0, N = 5;

    count = Mincookie(N);
    cout << "最小饼干数:" << count << endl;

    //_getch();
    return 0;
}

猜你喜欢

转载自blog.csdn.net/u013453604/article/details/51205169