首页 > 其他分享 >2558. 从数量最多的堆取走礼物

2558. 从数量最多的堆取走礼物

时间:2023-10-28 11:56:06浏览次数:32  
标签:堆取 2558 元素 long gifts int heap 礼物

1.题目介绍

给你一个整数数组 gifts ,表示各堆礼物的数量。每一秒,你需要执行以下操作:
选择礼物数量最多的那一堆。
如果不止一堆都符合礼物数量最多,从中选择任一堆即可。
选中的那一堆留下平方根数量的礼物(向下取整),取走其他的礼物。
返回在 k 秒后剩下的礼物数量。

示例 1:
输入:gifts = [25,64,9,4,100], k = 4
输出:29
解释:
按下述方式取走礼物:

  • 在第一秒,选中最后一堆,剩下 10 个礼物。
  • 接着第二秒选中第二堆礼物,剩下 8 个礼物。
  • 然后选中第一堆礼物,剩下 5 个礼物。
  • 最后,再次选中最后一堆礼物,剩下 3 个礼物。
    最后剩下的礼物数量分别是 [5,8,9,4,3] ,所以,剩下礼物的总数量是 29 。

示例 2:
输入:gifts = [1,1,1,1], k = 4
输出:4
解释:
在本例中,不管选中哪一堆礼物,都必须剩下 1 个礼物。
也就是说,你无法获取任一堆中的礼物。
所以,剩下礼物的总数量是 4 。

提示:
1 <= gifts.length <= 103
1 <= gifts[i] <= 109
1 <= k <= 103

2.题解

具体关于堆的知识可参考:C++ 语法结构--堆

2.1 堆(使用优先级队列创建)

priority_queue 可以提供堆没有的优势,它可以自动保持元素的顺序;但我们不能打乱 priority_queue 的有序状态,因为除了第一个元素(top),我们无法直接访问它的其他元素。
使用一个最大堆维护各堆礼物的数量,弹出k次最大值,并进行平方根处理后,再重新插入最大堆。最后,最大堆中所有礼物的数量之和就是我们要返回的答案

class Solution {
public:
    long long pickGifts(vector<int>& gifts, int k) {
        priority_queue<int> p(gifts.begin(), gifts.end());
        while (k--){
            int num = p.top();
            p.pop();
            p.push(int(sqrt(num)));
        }
        // 求和
        long long res = 0;
        while (!p.empty()){
            res += p.top();
            p.pop();
        }
        return res;
    }
};

2.2 堆(使用C++内置的make_heap函数)

思路

使用 make_heap() 创建的堆可以提供一些 priority_queue 没有的优势:

  1. 可以访问堆中的任意元素,而不限于最大的元素,因为元素被存储在一个容器中,就像是我们自己的 vector。这也提供了偶然破坏元素顺序的可能,但是总可以调用 make_heap()来还原堆。
  2. 可以在任何提供随机访问迭代器的序列容器中创建堆。这些序列容器包括普通数组string 对象自定义容器。这意味着无论什么时候需要,都可以用这些序列容器的元素创建堆,必要时,可以反复创建。甚至还可以为元素的子集创建堆。

题解中的做法最后在求剩下元素之和的时候使用的是pop除所有元素,因此时间复杂度应该为\(O(n\cdot\text{log }n)\),而不是\(O(k\cdot\text{log }n)\)。为了不通过pop的方法弹出所有元素来遍历优先级队列,可以使用C++内置的make_heap函数来处理:

代码

class Solution {
public:
    long long pickGifts(vector<int>& gifts, int k) {
        make_heap(gifts.begin(), gifts.end());
        for (int i = 0; i < k ;i ++) {
            pop_heap(gifts.begin(), gifts.end());
            *gifts.rbegin() = (int)(sqrt(*gifts.rbegin()));
            push_heap(gifts.begin(), gifts.end());
        }
        return accumulate(gifts.begin(), gifts.end(), 0ll);
    }
};

标签:堆取,2558,元素,long,gifts,int,heap,礼物
From: https://www.cnblogs.com/trmbh12/p/17793914.html

相关文章

  • 力扣2558.从数量最多的堆取走礼物
    给你一个整数数组 gifts ,表示各堆礼物的数量。每一秒,你需要执行以下操作:选择礼物数量最多的那一堆。如果不止一堆都符合礼物数量最多,从中选择任一堆即可。选中的那一堆留下平方根数量的礼物(向下取整),取走其他的礼物。返回在 k 秒后剩下的礼物数量。 示例1:输入:gifts......
  • 包管理工具-yarn的特别礼物
    yarn的特别礼物在终端命令上,yarn不仅仅是对npm的命令做了一个改名,还增加了一些原本没有的命令,这些命令在某些时候使用起来非常方便yarncheck使用yarncheck命令,可以验证package.json文件的依赖记录和lock文件是否一致这对于防止篡改非常有用yarnaudit使用yarnaudit......
  • BZOJ 生日礼物
    题目背景翰翰18岁生日的时候,达达给她看了一个神奇的序列$A_1,A_2,\dots,A_n$。她被允许从中选择不超过$M$个连续的部分作为自己的生日礼物。翰翰想要知道选择元素之和的最大值。你能帮助她吗?解题思路可以先合并序列中连续的同为正或负的值,使原序列变为一个一正一......
  • 剑指 Offer 47. 礼物的最大价值(中等)
    题目:classSolution{public:intmaxValue(vector<vector<int>>&grid){if(grid.empty())return0;//要考虑棋盘为空的情况直接返回0vector<vector<int>>dp(grid.size(),vector(grid[0].size(),0));//定义一个和棋盘同样大小的dp......
  • 社区交友源码支持聊天私聊/礼物系统/直播系统/缘分匹配+搭建教程
    功能:社区动态,即时聊天,私聊,好友系统,礼物系统,直播系统,缘分匹配,金币系统  免费下载链接:提取码:lsp6后端安装说明:环境nginx,php7.3,MySQL5.6一、后端安装说明:1.删除config/install.lock输入程序所在网址即可自动安装2.php需要开启https支持3.安装完成删除install.lock二、前端安装编......
  • TZOJ8036--生日礼物
    题目简述:给你n个数,让你选取不超过m个连续的区间,区间不重叠,求区间总和最大。标准输入522-32-12标准输出5思路:1.很显然能够想到把原数组简化成形如一正一负的数组。2.特殊情况,当正数连续块小于等于m时答案很显然是所有正数相加。3.一般情况,当正数连......
  • 端午节的礼物
    祝福:  大家端午节快乐苦闷我从来不知道什么是苦闷,失败了再来,前途是自己努力创造出来的。—— 徐特立往往人们在说“道理都明白,可就是做不到”时,内心里想的全是自己那一套,沉浸在自己的苦水中,根本没有去照着道理思维,这就好比拿着药方而不服药一样,自然没有用。......
  • 2558. 从数量最多的堆取走礼物
    2558.从数量最多的堆取走礼物 给你一个整数数组gifts,表示各堆礼物的数量。每一秒,你需要执行以下操作:选择礼物数量最多的那一堆。如果不止一堆都符合礼物数量最多,从中选择任一堆即可。选中的那一堆留下平方根数量的礼物(向下取整),取走其他的礼物。返回在k秒后剩......
  • 情人节礼物,看你中奖没有?
    阅读文本大概需要2分钟。今天是七夕节,估计大家已经在朋友圈、同事、同学那里吃的狗粮够多了,这里就不虐大家了,今天给大家送福利安慰下大家。首先头条推送了一条深度好文,看似简单的两个字其实蕴含着深刻的道理,之所以让你们加班,就是让你们可以观察下今天还在公司加班的异性,那基本都......
  • 互送礼物
     #include<iostream>#include<map>#include<bits/stdc++.h>usingnamespacestd;map<string,int>name_mon;intmain(intargc,char**argv){ stringname[15],zname,pname; intn,mon,m; cin>>n; for(inti=0;i<n;i++){ ......