首页 > 牛客网第三次模拟笔试----编程第三题
头像
黑猫爱小鹿
发布于 2021-06-25 14:37
+ 关注

牛客网第三次模拟笔试----编程第三题

牛客网第三次模拟笔试----编程第三题

题目

大意,就是有一个数组

eg input[1,5,2,6]

要输出的结果就是一个相同大小的数组h h[i]代表的含义就是,将输入数组中的每一位都变成input[i]所需与的操作数,操作只允许在别的位上加1或者减一

思路

==思路就是前缀和,如过数组长度比较小,那么就可以用map来进行题解==

什么是前缀和,前缀和有什么用

sum[i]代表的是[0---i-1]的这个一个区间的和

==那么好处和作用就很明显,就是能够快速的计算某一个区间的和==

那么以 [1,5,2,6]为例,要把所有的数都变成1,那么其实就只需要知道整个==数组的和减取数组个数*1的绝对值==。

也就是abs(1+5+2+6-(1*4))=10

那么同样的要把所有的数字变成5,按照上面的思路有

5结尾的和减去前面数的个数*5的绝对值 + 5开头到结尾的和减去后面的个数*5的绝对值

也就是abs(1+5-(25))+abs(5+2+6-(3\5)) = 4+2=6 || ==但是实际上是8==

为什么呢,其实就是,[+4,0,+3,-1],明显就是后面的正负抵消了,所以算出来是6,这时候怎么解决,就要把正的全部放在后面,负的全部就要放在前面,就需要排序。同时需要记住下标,这样才可以记住在哪里插入

程序

#include <algorithm>
#include <iostream>
#include <vector>

using namespace std;

vector<int> GetRes(vector<int>& data) {
  vector<pair<int, int>> sort_data;
  for (int i = 0; i < data.size(); i++) {
    sort_data.push_back({data[i], i});
  }

  // 自定义排序函数
  auto cmp = [&](pair<int, int>& a, pair<int, int>& b) -> bool {
    if (a.first < b.first) {
      return true;
    } else {
      return false;
    }
  };

  // 排序
  sort(sort_data.begin(), sort_data.end(), cmp);

//   for (auto value : sort_data) {
//     cout << value.first << " " << value.second << " | ";
//   }
//   cout << endl;

  // 进行前缀和计算
  vector<int> res(data.size());
  vector<int> sum(data.size() + 1);
  data[0] = 0;
  for (int i = 0; i < sort_data.size(); i++) {
    sum[i + 1] = sum[i] + sort_data[i].first;
  }

  // 开始进行计算,注意前缀和的意义就是[0~i-1]个数字的和

  // 开始进行计算
  for (int i = 0; i < sort_data.size(); i++) {
    int result = 0;
    // 计算前半部分
    int front = abs(sum[i + 1] - sort_data[i].first * (i + 1));
    // 计算后半部分
    int back =
        abs(sum[data.size()] - sum[i] - sort_data[i].first * (data.size() - i));

    result = front + back;
    res[sort_data[i].second] = result;
  }
  return res;
}

int main() {
  vector<int> data = {2, 3, 3, 5, 1};

  auto res = GetRes(data);

  for (auto value : res) {
    cout << value << " ";
  }
  cout << endl;
}

全部评论

(0) 回帖
加载中...
话题 回帖

相关热帖

近期精华帖

热门推荐