P1878 舞蹈课(详解)c++
题目链接:P1878 舞蹈课 - 洛谷 | 计算机科学教育新生态
1.题目解析


1:我们可以发现任意两个相邻的都是异性,所以他们的舞蹈技术差值我们都要考虑,4和2的差值是2,2和4的差值是2,4和3的差值是1,根据题目找到1这个最小差值后,输出这一对舞伴的编号即下标3和4,再输出队列里面还剩的另一队舞伴的编号1和2,这里成功出列了两对舞伴,所以先输出总对数2再输出3 4再输出1 2
2.算法原理
解法:利用小根堆存所有相邻异性的差值,然后每次拿出最小的即可

举个例子,把全部相邻异性的差值算出来之后,拿最小的差值,此时最小的差值是2,根据题目如果不止一对,那么最左边的那一对出列,所以让2号3号舞伴出列,接着继续让下一个差值最小的舞伴出列,这个想法很正确,就是利用堆存放相邻异性的差值,然后每次拿出最小的就行了,但是这个想法会很多问题
1.取出相邻的一对异性之后,他们的左右,有可能变成新的一对
比如现在让最小差值为2的一对舞伴出列,原来在他们左边的男生和右边的女生会组成一对新的舞伴,如何能做到快速地删除完一个之后,还能把左右两个连接起来呢,就可以利用双向链表存队列
比如2和4舞伴出列后,让10指向7,7指向10就可以得到一个新队列,利用双向链表存队列,就可以实现删除一对舞伴后,只需修改指针,就可以快速地确定另一个,并且把新的队列还原出来

2.堆中,有可能存在已经出列的人
堆中存放这5个差值8 2 3 2 8,最小差值为2的一对舞伴出列后,1号和4号舞伴产生新的差值3,并把它放到堆里,2号,3号舞伴出列后,8和3就变成了无效元素,但它们还在堆里,此时我拿出3,再输出下标,就有可能出错,所以要杜绝这种情况,创建一个bool数组标记一下即可;true表示出列,false表示没出列,假如我把3拿出来,再判断他对应的舞伴3和4是否有出列的情况,如果有就不对这个3进行处理
3.堆中存什么?
我们要知道技术差以及左边的人是谁以及右边的人是谁,<技术差,左编号,右编号>,这样就能还原双向链表,把技术差拿到,知道左编号和右编号,通过修改指针就可以还原
代码
//舞蹈课
#include <iostream>
#include <vector>
#include <queue>
#include <cmath>using namespace std;const int N = 2e5 + 10;int n;
int s[N]; //标记男女 - 1/0//双向链表存数据
//数据是从左向右依次进来的,4的右边就是2,2的左边就是4,
//直接把它定义出来就行了,就不需要h,id这些指针了
int e[N];
int pre[N], ne[N];struct node {int d; //技术差int l, r; //左右编号//小根堆,大元素下坠 bool operator <(const node& x) const{//根据题目如果不止一对,那么最左边的那一对出列//可以知道技术差有可能相等,所以技术差相等的时候可以根据左编号定义小根堆if (d != x.d) return d > x.d;else return l > x.l;}
};priority_queue<node> heap;
bool st[N]; //标记已经出列的人int main()
{cin >> n; for (int i = 1; i <= n; ++i){char ch; cin >> ch;if (ch == 'B') s[i] = 1;}for (int i = 1; i <= n; ++i){cin >> e[i];//直接创建双向链表pre[i] = i - 1;ne[i] = i + 1;}ne[n] = 0; //0表示后面没有元素//1.先把所有的异性放进堆里for (int i = 2; i <= n; ++i){//如果当前性别和前一个人的性别不一样if (s[i] != s[i - 1]){heap.push({ abs(e[i] - e[i - 1]), i - 1, i });}}//2.提取结果//我们最后要先输出有多少对出列,所以要先把结果存起来vector<node> ret; //暂存结果//堆里还要异性就一直出列while (heap.size()){node t = heap.top(); heap.pop();int d = t.d, l = t.l, r = t.r;//l、r其中任何一个标记ture,说明对应的位置里有人已经出列了if (st[l] || st[r]) continue;ret.push_back(t);st[l] = st[r] = true; //标记l或r已经出列//维护双向链表ne[pre[l]] = ne[r];pre[ne[r]] = pre[l];//判断新的左右是否会成为一对,左和右有可能不存在,判断异性就无意义//如果l的编号是1,1的左边是不存在人的,所以也要判断l/r是否存在int left = pre[l], right = ne[r];if (left && right && s[left] != s[right]){heap.push({ abs(e[left] - e[right]), left, right });}}cout << ret.size() << endl; for (auto& x : ret){cout << x.l << " " << x.r << endl;}return 0;
}
也可以用pair存结果
//暂存结果vector<pair<int, int>> ret;//模拟出列过程while (heap.size()){node t = heap.top(); heap.pop();int d = t.d, l = t.l, r = t.r;if (st[l] || st[r]) continue; //对应舞伴已出列则不处理//记录结果ret.push_back({ l,r }); st[l] = st[r] = true; //标记已出列//更新双向链表int left = pre[l], right = ne[r];ne[left] = right;pre[right] = left;//检查新的相邻是否为异性组合//l和r如果是1或者n,那便没有左边人或右边人if (left && right && s[left] != s[right]){heap.push({ abs(e[left] - e[right]), left , right });}}cout << ret.size() << endl;for (auto& x : ret){cout << x.first << " " << x.second << endl;}
相关文章:
P1878 舞蹈课(详解)c++
题目链接:P1878 舞蹈课 - 洛谷 | 计算机科学教育新生态 1.题目解析 1:我们可以发现任意两个相邻的都是异性,所以他们的舞蹈技术差值我们都要考虑,4和2的差值是2,2和4的差值是2,4和3的差值是1,根…...
何须付费免费它不香吗
聊一聊 又是一年开学季。 开学了发一些应时期的小软件。 今天给大家分享一款学校班级课程表工具。 这款工具可以投放在学校电子大屏上。 支持学校的白板软件。 软件介绍 学校班级课程表 工具界面清爽,信息能一目了然。 虽然看感觉功能简单,但每个…...
ELK组成及实现原理
ELK是由三个主要组件组成的日志处理和搜索平台,分别是: Elasticsearch:Elasticsearch 是一个基于Lucene构建的开源搜索引擎,提供强大的搜索、分析功能。它负责存储和索引所有数据,并提供实时搜索能力。数据可以通过HTT…...
【Vue3源码解析】响应式原理
源码环境搭建 【Vue3源码解析】应用实例创建及页面渲染-CSDN博客 写文章时的Vue 版本: "version": "3.5.13",针对单个包进行开发环境打包、测试。 pnpm run dev reactivityreactive 创建响应式对象 packages/reactivity/src/reactive.ts …...
servlet中的ServletContext
设置、获取ServletContext配置信息 与ServletConfig不同的是,所有Servlet共享一份ServletContext 在web.xml中设置配置信息 <?xml version"1.0" encoding"UTF-8"?> <web-app xmlns"https://jakarta.ee/xml/ns/jakartaee"x…...
第1825天 | 我的创作纪念日:缘起、成长经历、大方向
目录 缘起一、成为创作者的初心(一)好记性不如烂笔头(二)文档可以帮助多个人解决同一个问题(三)加深自己对问题的理解,对技术的研究 二、实战项目中的经验分享(一)项目背…...
如何在 Mac 上解决 Qt Creator 安装后应用程序无法找到的问题
在安装Qt时,遇到了一些问题,尤其是在Mac上安装Qt后,发现Qt Creator没有出现在应用程序中。通过一些搜索和操作,最终解决了问题。以下是详细的记录和解决方法。 1. 安装Qt后未显示Qt Creator 安装完成Qt后,启动应用程…...
Java 设计模式之迭代器模式
文章目录 Java 设计模式之迭代器模式概述UML代码实现Java的迭代器 Java 设计模式之迭代器模式 概述 迭代器模式(Iterator),提供一种方法顺序访问一个聚合对象中的各个元素,而又不暴露该对象的内部表示。 UML Iterator:迭代器接口ÿ…...
登录演示和功能拆解
登录演示和功能拆解 表单基础校验实现 1. 基础双向绑定 <template><el-form><el-form-item label"账号"><el-input v-model"formData.username" /></el-form-item><el-form-item label"密码"><el-inpu…...
DeepSeek深度求索API多线程批量写原创文章软件-ai痕迹极低
DeepSeek是一款由国内人工智能公司研发的大型语言模型,拥有强大的自然语言处理能力,能够理解并回答问题,还能辅助写代码、整理资料和解决复杂的数学问题。 与OpenAI开发的ChatGPT相比,DeepSeek不仅率先实现了媲美OpenAI-o1模型的…...
Redis进阶使用
在日常工作中,使用Redis有什么需要注意的? 设置合适的过期时间。尽量避免大key问题,避免用字符串存储过大的数据;避免集合的数据量太大,要定期清除。 常用的数据结构有哪些?用在什么地方? 按…...
Python常见面试题的详解6
1. 按字典 value 值排序 要点:对于给定字典,使用 sorted() 函数结合 items() 方法,依据 value 进行排序,也可以定义一个通用函数,支持按 value 升序或降序排序。示例: python d {a: 1, b: 2, c: 3, d: …...
Linux基础之文件权限的八进制表示法
1. Linux 文件权限概述 在 Linux 中,每个文件或目录都有三种基本权限,分别是: 读权限 - r:允许查看文件内容。写权限 - w:允许修改文件内容。执行权限 - x:允许执行文件或进入目录。 每个文件或目录的权…...
数据结构与算法面试专题——堆排序
完全二叉树 完全二叉树中如果每棵子树的最大值都在顶部就是大根堆 完全二叉树中如果每棵子树的最小值都在顶部就是小根堆 设计目标:完全二叉树的设计目标是高效地利用存储空间,同时便于进行层次遍历和数组存储。它的结构使得每个节点的子节点都可以通过简…...
《On Java进阶卷》阅读笔记(五)
第7章 IO系统 I/O流: IO有很多不同的来源和去处,如文件、控制台网络连接等,而且还涉及需求以很多种方式,如顺序读取、随机访问、缓冲、字符、按行读取、按字读取等。 Java8的函数式流相关的类和IO流之间并无关联。 IO流隐藏了…...
《代码随想录》刷题笔记——回溯篇【java实现】
文章目录 组合组合总和 III电话号码的字母组合组合总和组合总和II思路代码实现 分割回文串※思路字符串分割回文串判断效率优化※ 复原 IP 地址优化版本 子集子集 II使用usedArr辅助去重不使用usedArr辅助去重 递增子序列※全排列全排列 II重新安排行程题意代码 N 皇后解数独直…...
数值积分:通过复合梯形法计算
在物理学和工程学中,很多问题都可以通过数值积分来求解,特别是当我们无法得到解析解时。数值积分是通过计算积分区间内离散点的函数值来近似积分的结果。在这篇博客中,我将讨论如何使用 复合梯形法 来进行数值积分,并以一个简单的…...
AcWing——3624. 三值字符串
双指针解法 #include<iostream> #include<unordered_map> using namespace std; int main() {int n; cin >> n;while(n--){unordered_map<char, int> tree;string s; cin >> s;int ans 0x7fffffff; for(int i 0, j 0; j < (int)s.size();…...
【JavaEE进阶】验证码案例
目 🌲实现说明 🎄Hutool介绍 🌳准备工作 🌴约定前后端交互接口 🚩接口定义 🚩实现服务器后端代码 🚩前端代码 🚩整体测试 🌲实现说明 随着安全性的要求越来越⾼…...
Uniapp 短视频去水印解析工具开发实现
最近搞了一个有意思的小工具——短视频去水印解析器!这玩意儿可以把短视频中的水印给抹掉,还能提取视频、封面等资源。整个项目用了 Uniapp 开发,做完后体验了一下,发现还挺顺手。今天就来跟大家聊聊实现思路和代码细节~ 需求分析…...
【C语言练习】080. 使用C语言实现简单的数据库操作
080. 使用C语言实现简单的数据库操作 080. 使用C语言实现简单的数据库操作使用原生APIODBC接口第三方库ORM框架文件模拟1. 安装SQLite2. 示例代码:使用SQLite创建数据库、表和插入数据3. 编译和运行4. 示例运行输出:5. 注意事项6. 总结080. 使用C语言实现简单的数据库操作 在…...
【碎碎念】宝可梦 Mesh GO : 基于MESH网络的口袋妖怪 宝可梦GO游戏自组网系统
目录 游戏说明《宝可梦 Mesh GO》 —— 局域宝可梦探索Pokmon GO 类游戏核心理念应用场景Mesh 特性 宝可梦玩法融合设计游戏构想要素1. 地图探索(基于物理空间 广播范围)2. 野生宝可梦生成与广播3. 对战系统4. 道具与通信5. 延伸玩法 安全性设计 技术选…...
Java多线程实现之Thread类深度解析
Java多线程实现之Thread类深度解析 一、多线程基础概念1.1 什么是线程1.2 多线程的优势1.3 Java多线程模型 二、Thread类的基本结构与构造函数2.1 Thread类的继承关系2.2 构造函数 三、创建和启动线程3.1 继承Thread类创建线程3.2 实现Runnable接口创建线程 四、Thread类的核心…...
Go 语言并发编程基础:无缓冲与有缓冲通道
在上一章节中,我们了解了 Channel 的基本用法。本章将重点分析 Go 中通道的两种类型 —— 无缓冲通道与有缓冲通道,它们在并发编程中各具特点和应用场景。 一、通道的基本分类 类型定义形式特点无缓冲通道make(chan T)发送和接收都必须准备好࿰…...
TSN交换机正在重构工业网络,PROFINET和EtherCAT会被取代吗?
在工业自动化持续演进的今天,通信网络的角色正变得愈发关键。 2025年6月6日,为期三天的华南国际工业博览会在深圳国际会展中心(宝安)圆满落幕。作为国内工业通信领域的技术型企业,光路科技(Fiberroad&…...
适应性Java用于现代 API:REST、GraphQL 和事件驱动
在快速发展的软件开发领域,REST、GraphQL 和事件驱动架构等新的 API 标准对于构建可扩展、高效的系统至关重要。Java 在现代 API 方面以其在企业应用中的稳定性而闻名,不断适应这些现代范式的需求。随着不断发展的生态系统,Java 在现代 API 方…...
【LeetCode】算法详解#6 ---除自身以外数组的乘积
1.题目介绍 给定一个整数数组 nums,返回 数组 answer ,其中 answer[i] 等于 nums 中除 nums[i] 之外其余各元素的乘积 。 题目数据 保证 数组 nums之中任意元素的全部前缀元素和后缀的乘积都在 32 位 整数范围内。 请 不要使用除法,且在 O…...
水泥厂自动化升级利器:Devicenet转Modbus rtu协议转换网关
在水泥厂的生产流程中,工业自动化网关起着至关重要的作用,尤其是JH-DVN-RTU疆鸿智能Devicenet转Modbus rtu协议转换网关,为水泥厂实现高效生产与精准控制提供了有力支持。 水泥厂设备众多,其中不少设备采用Devicenet协议。Devicen…...
QT开发技术【ffmpeg + QAudioOutput】音乐播放器
一、 介绍 使用ffmpeg 4.2.2 在数字化浪潮席卷全球的当下,音视频内容犹如璀璨繁星,点亮了人们的生活与工作。从短视频平台上令人捧腹的搞笑视频,到在线课堂中知识渊博的专家授课,再到影视平台上扣人心弦的高清大片,音…...
Python 高级应用10:在python 大型项目中 FastAPI 和 Django 的相互配合
无论是python,或者java 的大型项目中,都会涉及到 自身平台微服务之间的相互调用,以及和第三发平台的 接口对接,那在python 中是怎么实现的呢? 在 Python Web 开发中,FastAPI 和 Django 是两个重要但定位不…...
