笔试题4 -- 除2!(k次机会偶数除2求最小和)

news/2024/9/25 7:50:58/

除2!(k次机会偶数除2求最小和)

文章目录

  • 除2!(k次机会偶数除2求最小和)
    • 读懂题目
    • 方案一(基于multiset实现 -- 超时)
    • 方案二(改进算法--基于 priority_queue 实现)
    • 总结

题目链接: 除2! (nowcoder.com)

题目描述

给一个数组,一共有 n 个数。你能进行最多 k 次操作。

每次操作可以进行以下步骤:

  • 选择数组中的一个偶数 ai,将其变成 ai/2 。

现在你进行不超过 k 次操作后,让数组中所有数之和尽可能小。请输出这个最小的和。

输入描述

  • 第一行输入两个正整数 n 和 k ,用空格隔开

  • 第二行输入 n 个正整数 ai

数据范围

1≤n≤100000,1≤k≤109,1≤ai≤109

输出描述

一个正整数,代表和的最小值。

读懂题目

注意点:

可以用于缩小最后数组中所有数相加和的唯一方法是:

  • 将数组中某个偶数减半
  • 而减半次数最多有k次

我们需要知道这个减半操作有两个限制项:

  1. 偶数
  2. 最多执行k次

如果减半次数没有用完,数组中已经没有偶数了,那么减半操作也只能停止。

方案一(基于multiset实现 – 超时)

//使用 multiset:50%案例超时
int main() 
{int n = 0, k = 0;cin >> n >> k;vector<int> v(n, 0);for(int i = 0; i < n; i++){cin >> v[i];}multiset<int, greater<>> s(v.begin(), v.end());bool have_double_num = false;for(int i = 0; i < k; i++){int big_num = 0;for(auto it = s.begin(); it != s.end(); it++){if(*it % 2 == 0){big_num = *it;have_double_num = true;s.erase(it);break;}}big_num /= 2;s.insert(big_num);if(!have_double_num) { break; }}size_t sum = 0;for(auto num: s){sum += num;}cout << sum << endl;return 0;
}

提交截图:

在这里插入图片描述

复杂度分析:

  • 时间复杂度:由于 multiset 的每次插入和删除操作都是 O(log n),而且在最坏情况下,可能需要遍历整个 multiset 来找到偶数进行操作,因此总的时间复杂度是 O(n log n)。
  • 空间复杂度multiset 存储了所有的元素,因此空间复杂度是 O(n)。

方案二(改进算法–基于 priority_queue 实现)

代码示例:

// 使用 priority_queue: 通过全部用例
int main() {int n = 0, k = 0;cin >> n >> k;vector<int> v(n, 0);for(int i = 0; i < n; i++) {cin >> v[i];}// 使用优先队列来存储元素,最大的元素总是在队列的前面size_t sum = 0;priority_queue<pair<int, bool>> pq;for (int num : v) {if(num % 2 == 0)pq.push({num, num % 2 == 0});else{sum += num;}}while(k > 0 && !pq.empty()) {auto [big_num, is_even] = pq.top(); pq.pop();// 只有当最大的数是偶数时,我们才执行除以2的操作if(is_even) {pq.push({big_num / 2, (big_num / 2) % 2 == 0});k--;}else{sum += big_num;}}while(!pq.empty()) {sum += pq.top().first; pq.pop();}cout << sum << endl;return 0;
}

提交截图:

在这里插入图片描述

复杂度分析:

  • 时间复杂度priority_queue 的插入和删除最大元素的操作是 O(log n),并且由于您只处理最大的偶数,所以不需要遍历整个队列,总的时间复杂度是 O(k log n)。
  • 空间复杂度:与 multiset 类似,priority_queue 也存储了所有的元素,因此空间复杂度是 O(n)。

总结

​ 在解决这类优化问题时,选择合适的数据结构至关重要。虽然 multiset 提供了一个简单直观的解决方案,但它在处理大量数据时可能会导致超时。相比之下,priority_queue 提供了一个更高效的方法,特别是当操作次数 k 较大时。通过优先处理最大的偶数,我们能够显著减少所需的操作次数,从而在给定的时间限制内找到最小的和。


http://www.ppmy.cn/news/1430784.html

相关文章

【MySQL 数据宝典】【磁盘结构】- 002 数据字典

一、数据字典 ( Data Dictionary ) 1.1 背景介绍 我们平时使用 INSERT 语句向表中插入的那些记录称之为用户数据&#xff0c;MySQL只是作为一个软件来为我们来保管这 些数据&#xff0c;提供方便的增删改查接口而已。但是每当我们向一个表中插入一条记录的时候&#xff0c;MyS…

Environment Modules工具

Environment Modules工具 简介 Module是一个环境变量管理工具&#xff0c;可以很好的实现开发环境的切换。 具体可以查看官网文档 安装 安装&#xff08;安装完成之后需要exit重新登录一下才会生效&#xff09; yum install -y environment-modules命令介绍 module avai…

Vue2 基础学习-案例实践

数据管理信息的增删改查的实践 主要应用&#xff1a; 数据插值&#xff1a; {{xxx}}双向绑定&#xff1a;v-model点击事件函数&#xff1a;click列表xxx的增删改实现 xxx.push(row) 增加xxx.splice(id,1) 删除 一行{x,y} xxx[id]; 编辑 <!DOCTYPE html> <html la…

(避雷指引:管理页面超时问题)windows下载安装RabbitMQ

一、背景&#xff1a; 学习RabbitMQ过程中&#xff0c;由于个人电脑性能问题&#xff0c;直接装在windows去使用RabbitMQ&#xff0c;根据各大网友教程&#xff0c;去下载安装完之后&#xff0c;使用web端进行简单的入门操作时&#xff0c;总是一直提示超时&#xff0c;要么容…

mysql面试题七(集群)

目录 1.mySQL 中有哪些常见日志 错误日志&#xff08;Error Log&#xff09; 二进制日志&#xff08;Binary Log, Binlog&#xff09; 重做日志&#xff08;Redo Log&#xff09; 回滚日志&#xff08;Undo Log&#xff09; 慢查询日志&#xff08;Slow Query Log&#xf…

Vue3 Reactive和Ref

当你在使用Vue 3时&#xff0c;reactive 和 ref 是两个常用的响应式API。它们都是用来跟踪状态变化并在UI中进行响应式更新的。 1. ref ref 用于创建一个响应式的基本数据类型变量&#xff0c;例如数字、字符串等。它返回一个带有 .value 属性的对象&#xff0c;该属性包含了…

Linux 目录操作函数

目录操作函数 ls -l 可以查看目录中文件的信息&#xff0c;比如&#xff1a; petriXX:~/lesson01/05_io/目录操作函数$ ls -l a.txt -rw-r--r-- 1 petri petri 0 Apr 22 18:51 a.txtLinux系统中的目录操作函数&#xff1a; int rename(const char *oldpath, const char *new…

【C++提高】算法

算法 一、遍历算法1. for_each2. transform 二、查找算法1. find2. find_if3. adjacent_find4. binary_search5. count6. count_if 三、排序算法1. sort2. random_shuffle3. merge4. reverse 四、拷贝和替换算法1. copy2. replace3. replace_if4. swap 五、算术生成算法1. accu…