蓝桥杯 7. 晚会节目单

晚会节目单

原题目链接

题目描述

小明要组织一台晚会,总共准备了 n 个节目。然而晚会时间有限,他只能从中选择 m 个节目。

n 个节目是按照小明设想的顺序给定的,顺序不能改变

小明发现观众对于晚会的喜欢程度与前几个节目的好看程度有非常大的关系,他希望选出的第一个节目尽可能好看,在此前提下希望第二个节目尽可能好看,依次类推。

小明为每个节目定义了一个好看值,请你帮助他选择出 m 个节目,满足他的要求。


输入描述

  • 第一行包含两个整数 n, m,表示节目的总数和要选择的节目数。
  • 第二行包含 n 个整数,表示每个节目的好看值。

数据范围:

  • 1 ≤ n ≤ 10^5
  • 0 ≤ 节目的好看值 ≤ 10^5

输出描述

输出一行包含 m 个整数,为选出的节目的好看值,按选择顺序输出。


输入输出样例

输入

5 3
3 1 2 5 4

输出

3 5 4

样例说明

选择了第 1、4、5 个节目,得到的好看值序列是:3 5 4,在所有保持顺序的选择中是字典序最大的。

c++代码

#include<bits/stdc++.h>using namespace std;int n, m;
vector<int> arr, trees, tem;
unordered_map<int, vector<int>> mp;class node{
public:int val, num, index;
};void build(int p, int l, int r) {if (l == r) {trees[p] = arr[l];return;}int mid = (l + r) / 2;build(2 * p, l, mid);build(2 * p + 1, mid + 1, r);trees[p] = max(trees[2 * p], trees[2 * p + 1]);
}int ask(int p, int l, int r, int left, int right) {if (l >= left && r <= right) return trees[p];int mid = (l + r) / 2, a = 0, b = 0;if (mid >= left) a = ask(2 * p, l, mid, left, right);if (mid < right) b = ask(2 * p + 1, mid + 1, r, left, right);return max(a, b);
}void bfs() {node k, w;k.val = ask(1, 1, n, 1, n - m + 1), k.num = 0;queue<node> q;for (int x : mp[k.val]) {if (x > n - m + 1) break;k.index = x;q.push(k);}while(!q.empty()) {k = q.front(), q.pop();if (k.val < tem[k.num]) continue;else tem[k.num] = k.val;if (k.num == m - 1 || k.index + 1 > n || n - (m - k.num - 1) + 1 > n || k.index + 1 > n - (m - k.num - 1) + 1) continue;w.val = ask(1, 1, n, k.index + 1, n - (m - k.num - 1) + 1), w.num = k.num + 1;for (int x : mp[w.val]) {if (x <= k.index) continue;if (x > n - (m - k.num - 1) + 1) break;w.index = x, q.push(w);}}
}int main() {std::ios::sync_with_stdio(false), std::cin.tie(nullptr), std::cout.tie(nullptr);cin >> n >> m;arr = vector<int>(n + 1), trees = vector<int>(4 * n), tem = vector<int>(m);for (int i = 1; i <= n; i++) cin >> arr[i], mp[arr[i]].push_back(i);build(1, 1, n);bfs();for (int i = 0; i < m; i++) {cout << tem[i];if (i != m - 1) cout << " ";}return 0;
}

实现思路

讲一下我的思路

首先我对这道题目的理解是,我们需要频繁查询区间最大值。

我们来看样例

5 3

3 1 2 5 4

实际上只有3 1 2可以选,因为选择5 4组成不了3个数

区间[1, 3]查询最值为3

实际上我们选了3后,只需要在3 的后面找两个数,那么4不可以选,因为凑不了两个

区间[2, 3]查询最值为5

同理区间[5, 5]查询最值为4

最终答案为3 5 4

然而,样例不会都这么简单,肯定有些分数是重复的,具体怎么解决重复。看下面解析。

算法步骤

我们刚刚得出,这个题目需要频繁地区间查询最值,我们选择线段树来解决,线段树查询一次最值只要O(logn)的时间。

读取输入

cin >> n >> m;
vector<int> arr(n + 1);
for (int i = 1; i <= n; i++) cin >> arr[i], mp[arr[i]].push_back(i);

构造线段树,编写查询方法

vector<int> trees(4 * n);//线段树定义void build(int p, int l, int r) {//递归建树if (l == r) {trees[p] = arr[l];return;}int mid = (l + r) / 2;build(2 * p, l, mid);build(2 * p + 1, mid + 1, r);trees[p] = max(trees[2 * p], trees[2 * p + 1]);
}int ask(int p, int l, int r, int left, int right) {//函数返回[left, right]里面的最大值if (l >= left && r <= right) return trees[p];int mid = (l + r) / 2, a = 0, b = 0;if (mid >= left) a = ask(2 * p, l, mid, left, right);if (mid < right) b = ask(2 * p + 1, mid + 1, r, left, right);return max(a, b);
}build(1, 1, n);

bfs广度优先

前面提到可能有多个局部最大值,我们必须要考虑每一个局部最大值,才能得出最终最大值。

为了快速得出数组里面有多少个局部最大值,我们用哈希表去存每一个值的下标是什么。

unordered_map<int, vector<int>> mp;
for (int i = 1; i <= n; i++) cin >> arr[i], mp[arr[i]].push_back(i);

然后我们开始bfs广度优先

class node{
public:int val, num, index;//val指当前节点的值,num指当前节点应该是第几个数,index表示数组里对应的下标。
};void bfs() {node k, w;k.val = ask(1, 1, n, 1, n - m + 1), k.num = 0;//第一个数的范围是[1, n - m + 1],否则凑不齐m个数queue<node> q;for (int x : mp[k.val]) {if (x > n - m + 1) break;k.index = x;q.push(k);}while(!q.empty()) {k = q.front(), q.pop();if (k.val < tem[k.num]) continue;else tem[k.num] = k.val;if (k.num == m - 1 || k.index + 1 > n || n - (m - k.num - 1) + 1 > n || k.index + 1 > n - (m - k.num - 1) + 1) continue;//下一个数的范围是[k.index + 1, n - (m - k.num - 1) + 1]w.val = ask(1, 1, n, k.index + 1, n - (m - k.num - 1) + 1), w.num = k.num + 1;for (int x : mp[w.val]) {if (x <= k.index) continue;if (x > n - (m - k.num - 1) + 1) break;w.index = x, q.push(w);}}
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/78086.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

JavaScript如何实现类型判断?

判断一个数据的类型&#xff0c;常用的方法有以下几种&#xff1a; typeofinstanceofObject.prototype.toString.call(xxx) 下面来分别分析一下这三种方法各自的优缺点 typeof typeof的本意是用来判断一个数据的数据类型&#xff0c;所以返回的也是一个数据类型。但是会遇到下…

哈希表笔记(四)Redis对比Java总结

文章目录 一、基础结构对比数据结构定义Java HashMapRedis字典 主要区别与设计思路 二、关键操作API对比初始化Java HashMapRedis字典 添加元素Java HashMapRedis字典 查找元素Java HashMapRedis字典 删除元素Java HashMapRedis字典 扩容/重哈希操作Java HashMapRedis字典 三、…

docker拉取国内镜像

1. 场景 最近整了一个tencent云服务器&#xff0c;想要玩一下docker&#xff0c;结果发现拉不下来&#xff0c;镜像根本拉不下来。 2. 原因 1.云服务器无法访问外网&#xff1b; 2. 国内的很多公有镜像仓库都被封了&#xff1b; 3. 推荐 https://zhuanlan.zhihu.com/p/713…

Codeforces Round 1008 (Div. 2) C

C 构造 题意&#xff1a;a的数据范围大&#xff0c;b的数据范围小&#xff0c;要求所有的a不同&#xff0c;考虑让丢失的那个a最大即可。问题变成&#xff1a;构造一个最大的a[i] 思路&#xff1a;令a2是最大的,将a1,a3,a5....a2*n1&#xff0c;置为最大的b&#xff0c;将a4,a…

STM32 HAL库实现USB虚拟串口

1. 引言 在嵌入式系统开发中&#xff0c;USB 虚拟串口是一种非常实用的功能。它允许 STM32 微控制器通过 USB 接口与计算机进行通信&#xff0c;就像使用传统的串口一样。这种方式不仅简化了硬件设计&#xff0c;还提高了通信的灵活性和稳定性。STM32F407 系列微控制器具有强大…

JAVA EE_网络原理_UDP与TCP

人海中未遇见时&#xff0c;我将独自前行... ----------陳長生. 1.UDP协议 1.1.UDP协议端格式 UDP&#xff08;用户数据报协议&#xff09;是由 源端口&#xff0c;目标端口&#xff0c;长度&#xff0c;校验和&#xff0c;数据 5种结构组成。16位是UDP报文中字段的长度&#…

【免费】1992-2021年各省GDP数据/各省地区生产总值数据

1992-2021年各省GDP数据/各省地区生产总值数据 1、时间&#xff1a;1992-2021年 2、来源&#xff1a;国家统计局、统计年鉴 3、指标&#xff1a;GDP/地区生产总值 4、范围&#xff1a;31省 5、指标说明:国内生产总值&#xff08;GDP&#xff09;是一个国家或地区在一定时期…

C++11新特性_范围-based for 循环

based for 循环介绍 范围 - based for 循环&#xff08;Range-based for loop&#xff09;是 C11 引入的一种新的 for 循环语法&#xff0c;它可以更简洁地遍历容器和数组。 遍历数组&#xff1a;定义了一个整数数组 arr&#xff0c;使用范围 - based for 循环 for (int num :…

【Bootstrap V4系列】学习入门教程之 页面内容排版

Bootstrap V4 学习入门教程之 页面内容排版 按钮上的指针排版一、Global settings 全局设置二、Headings 标题2.1 Customizing headings 自定义标题2.2 Display headings 显示标题2.3 Lead 引导 三、Blockquotes 块引用3.1 Naming a source 命名源3.2 Alignment 对齐 四、Lists…

Flowable7.x学习笔记(十六)分页查询我的待办

前言 我的待办具体区分为3种情况&#xff0c;第一个就是办理人指定就是我&#xff0c;我可以直接审批&#xff1b;第二种就是我是候选人&#xff0c;我需要先拾取任务然后再办理&#xff1b;第三种是我是候选组&#xff0c;我需要切换到指定的角色去拾取任务再办理。如果任务已…

EBO的使用

EBO 其实就是个索引&#xff0c;绑定在相应的VAO中&#xff0c;用来描述绘制顺序。比如在OpenGL绘制三角形的时候&#xff0c;假设有四个顶点&#xff0c;我称他们分别为1&#xff0c;2&#xff0c;3&#xff0c;4号顶点&#xff0c;常规绘制三角形函数是按三个点为一组&#x…

界面控件DevExpress WPF v25.1预览 - AI功能增强(语义搜索)

DevExpress WPF拥有120个控件和库&#xff0c;将帮助您交付满足甚至超出企业需求的高性能业务应用程序。通过DevExpress WPF能创建有着强大互动功能的XAML基础应用程序&#xff0c;这些应用程序专注于当代客户的需求和构建未来新一代支持触摸的解决方案。 无论是Office办公软件…

零基础做自动驾驶集成测试(仿真)

图 1&#xff1a;使用 GPUDrive 进行极快的多代理模拟。上图&#xff1a;GPUDrive 中 Waymo Open Motion Dataset 场景的鸟瞰图&#xff0c;方框表示受控智能体&#xff0c;圆圈表示其目标。底部&#xff1a;相应的代理视图&#xff0c;以一个代理为中心。可以根据用户的目标轻…

EasyRTC嵌入式音视频实时通话SDK技术,打造低延迟、高安全的远程技术支持

一、背景 在当今数字化时代&#xff0c;远程技术支持已成为解决各类技术问题的关键手段。随着企业业务的拓展和技术的日益复杂&#xff0c;快速、高效地解决远程设备与系统的技术难题变得至关重要。EasyRTC作为一款高性能的实时通信解决方案&#xff0c;为远程技术支持提供了创…

【C语言常用字符串解析】

总结一下在 C 语言中用于字符串解析&#xff08;特别是从文件中读取行并提取数据&#xff09;的常用函数、 核心任务&#xff1a; 通常是从文件中读取一行文本&#xff08;一个字符串&#xff09;&#xff0c;然后从这个字符串中提取出需要的数据&#xff08;比如数字、单词等…

SpringTas定时任务使用详解

文章目录 Spring Task概述1、环境配置2.注解实现定时任务2.注解实现定时任务4. cron表达式详解&#xff1a; Spring Task概述 在开发中&#xff0c;我们经常会用到定时任务&#xff0c;而Spring Task 则是Spring提供的定时任务框架。 其它定时任务实现框架又jdk自带Timer和Qua…

数字智慧方案6172丨智慧医院扩建信息化整体规划方案(60页PPT)(文末有下载方式)

资料解读&#xff1a;智慧医院扩建信息化整体规划方案 详细资料请看本解读文章的最后内容。 在信息技术飞速发展的当下&#xff0c;医疗行业的信息化建设成为提升医疗服务水平、优化医院管理的关键路径。这份智慧医院扩建信息化整体规划方案&#xff0c;针对医院扩建过程中的信…

ts全局导入接口

为了在项目中全局导入 ITableColumn 接口&#xff0c;避免每次使用时手动导入&#xff0c;可以通过以下步骤实现&#xff1a; 1. 全局导入的实现方式 在 Vue 项目中&#xff0c;可以通过在 src 目录下创建一个 global.d.ts 文件&#xff0c;将 ITableColumn 接口声明为全局类型…

汽车启动原理是什么?

好的&#xff01;同学们&#xff0c;今天我们来讨论汽车的启动原理&#xff0c;重点分析其中的动力来源和摩擦力作用。我会结合物理概念&#xff0c;用尽量直观的方式讲解。 1. 汽车为什么会动&#xff1f;——动力的来源 汽车发动机&#xff08;内燃机或电动机&#xff09;工…

【音频】Qt6实现MP3播放器

1、简介 解码MP3有很多种方法,比如:FFmpeg、GStreamer、Qt、libmpg123 库等,下面介绍使用,只使用Qt的接口方法解码、播放MP3。 开发配置: 1)操作系统:Windows11 2)Qt版本:Qt6.5.1 3)编译器:MinGW_64 2、获取音频输出设备 QMediaDevices 用于获取媒体设备,包括音…