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; }