2022.8.20 网易笔试 长城数组 解题思路

今天考试时候脑子一团浆糊,晚上刷牙时候突然开窍,有了以下思路,如有错误还请各位大神指正!
思路:从头(两个或三个数字)开始构建长城数组,逐个添加新元素到数组内,每次添加更新需要的操作次数。
/* 第二题 长城数组

   长城数组 1 9 1 9, 2 5 2 5 2 5
   非长城数组 2 3 1 2

   给定一个数组,每次可对其中任意一数执行加1操作
   问最少几次可以把它变成长城数组
*/

#include <iostream>
#include <vector>

#define PRINT_TMP_VECTOR // 输出中间过程数组

using namespace std;

template <typename T>
const ostream& operator<< (ostream &output, const vector<T> vec) {
    for (T i : vec)
        output << i << " ";
}

/**
 * GreatWallVector: 已经确认为长城数组的数组,长度至少为3,由调用者保证。
 * n: 要新添加的数
 */
int insert2GreatWall(vector<int> &GreatWallVector, int n) {
    // 将n添加到GreatWallVector的末尾,并调整为新的GreatWallVector
    int size = GreatWallVector.size();
    if (size < 2) { // 起始数组长度需要大于等于2
        return 0;
    }

    int large, small;
    if (GreatWallVector.at(0) > GreatWallVector.at(1)) {
        large = GreatWallVector.at(0);
        small = GreatWallVector.at(1);
    } else {
        large = GreatWallVector.at(1);
        small = GreatWallVector.at(0);
    }
    
    if (GreatWallVector.at(size - 1) == large) { // 结尾元素是大值
        if (n <= small) {
            GreatWallVector.push_back(small);
            return small - n;
        } else {//if (n <= large) {
            // 与下一情况操作一致
        //} else {
            int i = size - 2, res = 0;
            while (i >= 0) {
                GreatWallVector.at(i) = n;
                res += (n - small);
                i -= 2;
            }
            GreatWallVector.push_back(n);
            return res;
        }
    } else {
        /*
        if (n <= small) {
            GreatWallVector.push_back(large);
            return large - n;
        } else */ if (n <= large) { // 与上一条件操作一致
            GreatWallVector.push_back(large);
            return large - n;
        } else {
            int i = size - 2, res = 0;
            while (i >= 0) {
                GreatWallVector.at(i) = n;
                res += (n - large);
                i -= 2;
            }
            GreatWallVector.push_back(n);
            return res;
        }
    }
}

int Conv2GreatWall(vector<int> vec) {
    int n = vec.size(), res = 0;
    if (n < 3) // n == 1 || n == 2
        return res;

    vector<int> tmp(vec.begin(), vec.begin() + 2);

    // 对前三位预处理
    int start;
    if (tmp.at(0) == tmp.at(1)) { // 如果前两位数字相同,则需要考虑第三位数字的大小
        start = 3;
        tmp.push_back(vec.at(2));
        if (tmp.at(2) == tmp.at(0)) { // 第三个数字也相同
            res += 1;
            tmp.at(1)++; // 中间的数字加1
        } else if (tmp.at(2) > tmp.at(0)) { // 第三个数字大于前两位
            res += tmp.at(2) - tmp.at(0);
            tmp.at(0) = tmp.at(2); // 操作使首位等于第三位
        } else { // 第三个数字小于前两位
            tmp.at(0)++; // 首位加1
            res += (1 + tmp.at(0) - tmp.at(2));
            tmp.at(2) = tmp.at(0); // 让第三位等于首位
        }
    } else { // 如果前两位数字不相同,则不需要考虑第三位,第三位与后面统一处理
        start = 2;
    }
    if (n > start) {
        for (int i = start; i < n; ++i) {
            res += insert2GreatWall(tmp, vec.at(i));

#ifdef PRINT_TMP_VECTOR
            cout << "Current tmp vector is : ";
            cout << tmp;
            cout << endl;
#endif

        }
    }
    return res;
}

int main() {
    while (1) {

    int n, tmp;
    vector<int> vec;
    cout << "Input the size of vector: " << endl;
    cin >> n;
    cout << "Input the vector elements: " << endl;
    while (n-- > 0) {
        cin >> tmp;
        vec.push_back(tmp);
    }
    cout << Conv2GreatWall(vec) << endl;

    }
    return 0;
}


#网易笔试##动态规划#
全部评论
分别记录奇偶数位的sum和max。然后就可以算出来了。
3 回复 分享
发布于 2022-08-21 00:34 浙江
能写这么长。。。。
点赞 回复 分享
发布于 2022-09-10 21:18 北京
想复杂了
点赞 回复 分享
发布于 2022-08-21 01:17 辽宁

相关推荐

04-30 21:35
已编辑
长安大学 C++
晓沐咕咕咕:评论区没被女朋友好好对待过的计小将可真多。觉得可惜可以理解,毕竟一线大厂sp。但是骂楼主糊涂的大可不必,说什么会被社会毒打更是丢人。女朋友体制内生活有保障,读研女朋友还供着,都准备订婚了人家两情相悦,二线本地以后两口子日子美滋滋,哪轮到你一个一线城市房子都买不起的996清高计小将在这说人家傻😅
点赞 评论 收藏
分享
点赞 评论 收藏
分享
评论
4
4
分享

创作者周榜

更多
牛客网
牛客企业服务