藍橋杯 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.pswp.cn/web/78086.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/78086.shtml
英文地址,請注明出處:http://en.pswp.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 用于獲取媒體設備,包括音…