/*Name: P1878_舞蹈课Copyright: Author: 巧若拙 Date: 01-03-17 07:42Description:
有n个人参加一个舞蹈课。每个人的舞蹈技术由整数来决定。在舞蹈课的开始,他们从左到右站成一排。
当这一排中至少有一对相邻的异性时,舞蹈技术相差最小的那一对会出列并开始跳舞。
如果不止一对,那么最左边的那一对出列。一对异性出列之后,队伍中的空白按原顺序补上
(即:若队伍为ABCD,那么BC出列之后队伍变为AD)。舞蹈技术相差最小即是ai的绝对值最小。
任务是模拟以上过程,确定跳舞的配对及顺序。输入输出格式输入格式:
第一行为正整数n(1<=n<=2*10^5):队伍中的人数。下一行包含n个字符B或者G,B代表男,G代表女。
下一行为n个整数ai(ai<=10^7)。所有信息按照从左到右的顺序给出。在50%的数据中,n<=200。输出格式:
第一行:出列的总对数k。接下来输出k行,每行是两个整数。按跳舞顺序输出,两个整数代表这一对舞伴的编号
(按输入顺序从左往右1至n编号)。请先输出较小的整数,再输出较大的整数。输入输出样例
输入样例#1:
4
BGBG
4 2 4 3
输出样例#1:
2
3 4
1 2 算法思路:
设置一个Node类存储每对舞伴的左右舞者下标l,r和舞技差值w。
一开始读取所有相邻的舞伴信息,并插入到最小堆。
然后执行以下循环体,直至最小堆为空:
记录堆顶元素的舞者下标(当前配对舞者),标注当前舞者已配对,并删除堆顶元素,
然后删除所有涉及已配对舞者的堆顶元素,确保下次提取的顶点是满足条件的配对。
接下来跳过所有已配对舞者,用其两侧的舞者填补空白,查看是否能形成新的配对,
若能配对,则生成新结点,并插入到最小堆。
注意:题目要求“如果不止一对,那么最左边的那一对出列”,所以建立最小堆的时候,
不仅仅要看w值,还要比较左侧舞者的编号,编号小的靠前。
所以重载>运算符的时候要同时比较w和l的值。 分点信息(鼠标移到方块上有详细信息)#1
AC
3ms/1589kB#2
AC
5ms/18207kB#3
AC
3ms/1593kB#4
AC
4ms/1589kB#5
AC
2ms/18207kB#6
AC
731ms/4039kB
#7
AC
676ms/3679kB#8
AC
721ms/3996kB#9
AC
749ms/3687kB#10
AC
409ms/20457kB
*/
#include<iostream>
#include<algorithm>
#include<math.h>
#include<queue>using namespace std;class Node
{public://  void PrintNode() {cout << l+1 << " " << r+1 << " --" << w << endl;}void SetNode(int p1, int p2, int v) {l = p1; r = p2; w = v;}int GetL() {return l;}int GetR() {return r;}int GetW() {return w;}friend bool operator < (const Node &op1, const Node &op2) {return op1.w < op2.w || (op1.w == op2.w && op1.l < op2.l);}private:int l, r;  //分别表示左右两个舞伴的下标 int w;
};template <typename type> class MinHeap
{public:MinHeap(int maxSize); //创建一个容量为maxSize的空堆   ~MinHeap() {delete []heap;} //析构函数const type & top() {return heap[0];} //返回堆顶的最小元素 bool empty(){return size == 0;} //判断是否为空堆 bool push(const type &x); //将x插入到最小堆bool pop(); //删除堆顶的最小元素private:type *heap;   //存放堆的元素的数组 int capacity; //堆的容量 int size;     //堆的长度,即当前元素个数 void FilterDown(int i); //从下标i到m自顶向下进行调整成为最小堆void FilterUp(int i); //从下标i到0自底向上进行调整成为最小堆
};template <typename type> MinHeap<type>::MinHeap(int maxSize)
{capacity = maxSize;heap = new type[capacity];size = 0;
}template <typename type> void MinHeap<type>::FilterDown(int i) //从下标i到堆的尾部自顶向下进行调整成为最小堆
{type t = heap[i];   //保存heap[i]的值以备放到适合的位置 int child = i * 2 + 1; //指向左孩子   while (child < size) //有左孩子 {if (child+1 < size && heap[child+1] < heap[child]) //有右孩子,且右孩子更小些,定位其右孩子   child++;  if (heap[child] < t)//用较小值覆盖其父亲结点的值,即将空位下滤到新的位置 {  heap[i] = heap[child];      i = child; child = i * 2 + 1;}  else  break;  }heap[i] = t;
}template <typename type> void MinHeap<type>::FilterUp(int i) //从下标i到0自底向上进行调整成为最小堆
{type t = heap[i];while (i > 0 && t < heap[i/2]) //若比父亲结点小,则用父亲结点的值覆盖该结点,即将空位上滤到新的位置 {heap[i] = heap[i/2];       i /= 2;}heap[i] = t;
}template <typename type> bool MinHeap<type>::push(const type &x) //将x插入到最小堆
{//从尾部插入并向上调整成最小堆,然后长度增1 heap[size++] = x;FilterUp(size-1); return true;
}template <typename type> bool MinHeap<type>::pop() //删除堆顶的最小元素
{heap[0] = heap[--size];//用尾部元素覆盖顶部元素,然后长度减1FilterDown(0); //顶部元素向下调整成最小堆return true;
}int main()
{Node t;const int size = 200000;MinHeap<Node> H(size);char S[size];int A[size];int n;cin >> n;for (int i=0; i<n; i++){cin >> S[i];}for (int i=0; i<n; i++){cin >> A[i];}for (int i=1; i<n; i++)//不同性别的都入队{if (S[i] != S[i-1]){t.SetNode(i-1, i, abs(A[i]-A[i-1])); H.push(t);}} bool F[size] = {0}; //标注是否已经配对成功 int P[size/2][2]; //存储配对成功的舞者编号 int s = 0;int l, r, p1, p2; //分别存储左右舞伴的下标while (!H.empty()){t = H.top();l = t.GetL();r = t.GetR(); F[l] = F[r] = true; //标注该对舞伴已配对P[s][0] = l + 1; //记录配对舞伴编号(下标+1) P[s++][1] = r + 1;do //除去重复配对的顶点,确保下次提取的顶点是满足条件的配对 {H.pop();if (H.empty())  break;t = H.top();p1 = t.GetL();p2 = t.GetR(); } while(F[p1] || F[p2]);//跳过已经配对的舞者while(l >= 0 && F[l]){l--;}while(r < n && F[r]){r++;}if (l>=0 && r<n && S[l] != S[r])//有缘千里来相会{t.SetNode(l, r, abs(A[l]-A[r])); H.push(t);}}cout << s << endl;for (int i=0; i<s; i++){cout << P[i][0] << " " << P[i][1] << endl;}system("pause");   return 0;
}

洛谷在线测试P1878_舞蹈课相关推荐

  1. 洛谷——P2381 圆圆舞蹈

    P2381 圆圆舞蹈 题目描述 熊大妈的乃修在时针的带领下,围成了一个圆圈舞蹈,由于没有严格的教育,奶牛们之间的间隔不一致. 奶牛想知道两只最远的奶牛到底隔了多远.奶牛A到B的距离为A顺时针走和逆时针 ...

  2. 洛谷 P1878 舞蹈课 —— 小顶堆

    This way 题意: 有 n个人参加一个舞蹈课.每个人的舞蹈技术由整数来决定.在舞蹈课的开始,他们从左到右站成一排.当这一排中至少有一对相邻的异性时,舞蹈技术相差最小的那一对会出列并开始跳舞.如果 ...

  3. 洛谷 深基 第4部分 基础数学与数论(19-21课)

    洛谷 深基 第4部分 基础数学与数论  第19章 位运算与进制转换 P1143 进制转换 https://www.luogu.com.cn/problem/P1143 洛谷P1143 进制转换的Pyt ...

  4. 【暖*墟】#洛谷网课1.30# 树上问题

    树上倍增 基环外向树DP DFS序与欧拉序 树链剖分 可以参考wjyyy的https://www.wjyyy.top/421.html wjyyy是这样说的: 树链剖分是一种优化,将树上最常经过的几条 ...

  5. 2021寒假——洛谷刷题计划(35题)

    (希望大家不要Copy) AC:Accept,程序通过. CE:Compile Error,编译错误. PC:Partially Correct,部分正确. WA:Wrong Answer,答案错误. ...

  6. 【c++算法刷题笔记】——洛谷2

    1. 洛谷练习--P1579 哥德巴赫猜想(升级版) 题目描述: 现在请你编一个程序验证哥德巴赫猜想. 先给出一个奇数n,要求输出3个质数,这3个质数之和等于输入的奇数. 输入格式: 仅有一行,包含一 ...

  7. 洛谷、牛客网、AcWing 刷题(python版)

    牛客网python专项练习整理(一) https://blog.csdn.net/weixin_41913008/article/details/87203468 牛客网剑指offer--python ...

  8. 深度优先搜索——First Step(洛谷 P3654)

    题目选自洛谷P3654 本题遍历每一个可以站人的点,然后利用dfs的思路判断每一个点向下和向右是否能满足条件:但是k=1时需要特判,因为k=1意味着向下和向右重复计算,需要除以2. 注意在dfs前先判 ...

  9. 排序——奖学金(洛谷 P1093)

    题目选自洛谷P1093 这里不再讲述各种基本排序实现,如想了解可以参考我之前的算法里的几种排序算法知识点. 主要讲述在竞赛过程中,我们如何将排序算法运用到解题当中来,一般情况下,需要用到排序的时候,我 ...

  10. 【洛谷】入门2 分支结构

    原题传送门 点我 P5710 [深基3.例2]数的性质 题目描述 一些数字可能拥有以下的性质: 性质 1:是偶数: 性质 2:大于 4 且不大于 12. 小A 喜欢这两个性质同时成立的数字:Uim 喜 ...

最新文章

  1. windows上安装Anaconda和python的教程详解
  2. Android 监听 WiFi 开关状态
  3. 深入理解JVM类文件格式
  4. spring里的controller之间的跳转
  5. Android 系统(75)---Android常用的网路框架
  6. Nginx反向代理的目录访问问题
  7. (MTT)连续能量函数最小化方法
  8. 零基础学模拟电路--3.同相放大器、反相放大器、加法器、减法器、积分器、微分器
  9. 虚拟机服务器都使用的机械硬盘吗,云服务器 有机械硬盘吗
  10. 用户相关命令与文件权限(普通、特殊、隐藏、ACL)
  11. APP跳转微信小程序,跳转微信公众号
  12. 用蓝牙构建一个sniffer来监听通话
  13. Ardunio开发实例-PCF8563 RTC模块
  14. 对于LSB的理解(位的LSB、模数转换的LSB
  15. OmniPeek11安装 (驱动安装)
  16. WebSupergoo 11.310 C#PDF库组件 WebSuper
  17. matlab仿真直流输电接地极系统,轻型高压直流输电系统的MATLAB仿真
  18. Hug pylons, not trees 拥抱电网,而非树木 | 经济学人20230408版双语精翻
  19. 网页自动提交Form表单的方法
  20. 基于jsp和servlet的蛋糕店售卖网站商城系统javaweb点心铺源码mysql

热门文章

  1. matlab怎么画lnx图像,inx图像(lnx的图像函数)
  2. Webgl(ThreeJS)空间测量\测距功能(附工程文件)
  3. excel文件因服务器未响应无法打开,excel打开显示兼容模式(未响应)
  4. html简单图片轮播居中,html简单图片轮播的实现
  5. network secruity studay day2
  6. libvlc 裁剪及编译
  7. c语言学习-1-Visual Studio 2019下载和安装
  8. 如何为长期旅行做准备
  9. SQL如何还原数据库
  10. linux两种库:动态库和静态库(共享库)说明