【问题描述】
有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
【样例输入2】
4
BGBB
1 1 2 3
【样例输出2】
1
1 2

【来源】

Noi导刊

题解:

(*)
Done By NOI导刊:
双向链表+堆
堆中存储:相邻异性的编号及技术差值。
按照技术差值为第一关键字,编号为第二关键字排序
双向链表用来快速寻找i号左边的人和右边的人。
算法流程:
1.将所有相邻的异性加入堆;
2.当堆中还有元素时,取出并删除堆顶,否则结束;
3.如果堆顶的两个人(x,y)有一个已经出列或者都出列了,跳到2
4.将x和y标记为已出列并加入答案,检查x左边和y右边的人是否为异性,如果是就加入堆;
5.将x和y从双向链表中删除,跳到2.
(*)

今天发现当初加了很多注释,所以发上来..

  1 Var
  2   i,j:longint;       //i,j 主程序中循环变量
  3   k,n:longint;      //k:配对成功数量 n:舞蹈课人数
  4   x,y:longint;     //临时左右配对编号
  5   DP:longint;     //总可能配对方案数
  6   a,b,c:Array[0..301001] of longint;
  7     //a:技术差值 b:技术值 c:判断队伍中人是否已配对成功
  8   DA,DC:array[0..301001,0..2] of longint;
  9     //DA:成对舞伴编号 DC:配对左右编号
 10   s:Array[0..301001] of Char;  //s:存放性别
 11   xx:BooLean;   //判断方案是否产生(即是否配对成功)..
 12 ProceDure Sort(h,n:longint);
 13   //按照技术差值为第一关键字,编号为第二关键字排序
 14   Var
 15     i,j,Tt,Head,Tail,z:longint;
 16   Begin
 17     i:=h;                     //i,第一指针,前
 18     j:=i shl 1;             //j,第二指针,后
 19     Tt:=a[i];              //Tt为初始最小差值
 20     Head:=DC[i,0];   //配对左侧位置
 21     Tail:=DC[i,1];      //配对右侧位置
 22     //z:=i;
 23     While j<=n do
 24       Begin
 25         if ((j<n) And ( (a[j]>a[j+1]) Or ( (a[j]=a[j+1]) And (DC[j,0]>DC[j+1,0]) ) ) ) Then Inc(j);
 26         //如果j还小于n并且第j个大于第j+1个或者第j个等于第j+1个但第j个在第j+1个的右边,那么指针j++
 27         //即如果当前指针在链表中,且右移后得到的差值及配对方案仍由于当前,指针右移
 28         if ((Tt<a[j]) Or ( (Tt=a[j]) And (Head<DC[j,0]) ) ) then Break;
 29         //如果第j个比Tt大或者Tt跟第j个一样大但头指针比第j个的头靠左,那么退出循环
 30         //即若当前指针所指的差值比已知最小值大,或虽相等配对方案在队伍更右侧,排序结束,退出
 31         a[i]:=a[j];
 32         DC[i,0]:=DC[j,0];
 33         DC[i,1]:=DC[j,1];
 34         //更新a,DC数组为当前最优解
 35         //由上两个if判断可得,当前j指针所指的差值及方案,比原方案的要优
 36         i:=j;
 37         j:=j Shl 1;
 38        //更新i, j两指针
 39        //查看由原来j开始到j*2++段中是否仍能找到更优解
 40       End;
 41     a[i]:=Tt;
 42     DC[i,0]:=Head;
 43     DC[i,1]:=Tail;
 44     //由于While循环中的判断,当前的Tt已经是剩余最小差值,DC得到了当前最小差值的最靠左配对
 45   End;
 46 Begin
 47   Readln(n);
 48   For i:=1 to n do
 49     Read(s[i]);
 50   Readln;
 51   For i:=1 to n do
 52     Begin
 53       Read(b[i]);
 54       if (i<>1) And (s[i]<>s[i-1]) Then  //若异性,则
 55         Begin
 56          Inc(DP);                        //可配对数量
 57           a[DP]:=Abs(b[i]-b[i-1]);        //配对技术差值
 58           DC[DP,0]:=i-1;                  //配对左标号
 59           DC[DP,1]:=i;                    //配对右标号
 60         End;
 61     End;
 62   //初始化,找到相邻可配对,得到其技术差值,存入a数组,DC[x,0]表示前节点,DC[x,1]表示后节点
 63   //堆中存储:相邻异性的编号及技术差值。
 64   For i:=DP Shr 1 downto 1 do Sort(i,DP);//1对=2人...
 65   For i:=1 to n shr 1 do     //1对=2人....
 66     Begin
 67       xx:=False;           //判断第i对是否出列..
 68       While Not xx do
 69          Begin
 70             x:=DC[1,0];
 71             y:=DC[1,1];       //当前配对左右编号分别赋入x,y
 72             if (c[x]=0) and (c[y]=0) Then  //若当前所指的配对方案两人均未出列,选择该方案,2人出列
 73               Begin
 74                  c[x]:=1;
 75                  c[y]:=1;             //两人出列
 76                  DA[i,0]:=x;
 77                  DA[i,1]:=y;        //Answer赋值
 78                  xx:=True;         //第i对已选择
 79                  While (c[x]=1) And (x>=0) do Dec(x);    //更新左指针
 80                  While (c[y]=1) And (y<=n+1) do Inc(y);  //更新右指针
 81                  if (x>0) And (y<=n) And (s[x]<>s[y]) Then //若当前指针合法,且指向两个异性,则
 82                    Begin
 83                      a[1]:=Abs(b[x]-b[y]);     //更新为当前两人差值
 84                      DC[1,0]:=x;
 85                      DC[1,1]:=y;              //首初始化为当前两人标号
 86                      Sort(1,DP);               //归队,排序
 87                    End;
 88               End
 89           Else      //若当前所指“最优”配对方案中,2人至少1人出列
 90               Begin
 91               a[1]:=a[DP];  //更新为最末(最可能没出队的...)
 92               DC[1,0]:=DC[DP,0];
 93               DC[1,1]:=DC[DP,1]; //标号随之更新..
 94               Dec(DP);           //最终可能方案数 DP--
 95               Sort(1,DP);        //重新排序
 96              End;
 97          if DP=0 Then Break;   //若已无方案,退出
 98          End;
 99       if DP=0 Then Break;       //若已无方案,退出
100      End;
101   k:=0;                          //最终配对数量初始化
102   For j:=1 to i do               //由上,最多有i对..
103     if (DA[j,0]<>0) then Inc(k); //若DA中存在信息,说明有配对存在
104   Writeln(k);                    //输出最终配对数量
105   For i:=1 to k do
106     Writeln(DA[i,0],' ',DA[i,1]); //输出成对舞伴编号...
107 End.
108 (*)程序中注释 Written By Catch-22.S.In(*)

转载于:https://www.cnblogs.com/Catch-22/archive/2012/11/07/2759368.html

舞蹈课(dance.cpp/c/pas)相关推荐

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

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

  2. 洛谷 P2071 座位安排 seat.cpp/c/pas

    P2071 座位安排 seat.cpp/c/pas 题目背景 公元二零一四年四月十七日,小明参加了省赛,在一路上,他遇到了许多问题,请你帮他解决. 题目描述 已知车上有N排座位,有N*2个人参加省赛, ...

  3. 2012_p3 摆花 (flower.cpp/c/pas)

    问题 F: 2012_p3 摆花 (flower.cpp/c/pas) 时间限制: 1 Sec  内存限制: 128 MB 提交: 16  解决: 9 [提交][状态][讨论版][命题人:外部导入] ...

  4. Problem 2 西行寺幽幽子(spring.cpp/c/pas)

    Problem 2  西行寺幽幽子(spring.cpp/c/pas) 题目描述  在幻想乡,西行寺幽幽子是以贪吃闻名的亡灵.不过幽幽子可不是只会吃,至少她还管理着 亡灵界.话说在幽幽子居住的白玉楼有 ...

  5. 晶晶的朋友(invite.cpp/c/pas)

    晶晶的朋友贝贝约晶晶下周一起去看展览,但晶晶每周的1.3.5有课必须上课,请帮晶晶判断她能否接受贝贝的邀请,如果能输出YES:如果不能则输出NO.注意YES和NO都是大写字母! 输入格式: 输入仅一个 ...

  6. 计算机微课论文参考文献,微课教学学论文参考文献 微课教学参考文献怎么写...

    精选了[100个]关于微课教学学论文参考文献供您后续的写作参考,在写微课教学论文之前,很多大学生总是被微课教学参考文献怎么写难倒怎么办?请阅读本文! 一.微课教学论文参考文献范文 [1]"零 ...

  7. 高中计算机课代表优秀事迹,开学啦 | 课代表欧弟的优秀事迹

    原标题:开学啦 | 课代表欧弟的优秀事迹 伴随着9月的到来 开学的号角也陆续在各个学校响起~ 欧满斗学校校长麻麻 欧满斗学校开学啦~ 虽然很多学生不想开学,哈哈~ 26分钟前 北斗,花圆满,粑粑,欧弟 ...

  8. set的用法及短语_人教版九全Unit 14重点短语、重点句型、课文讲解

    点击上方蓝字关注我们 于茫茫书海中,为你寻找更适合自己成长的有效资源和那些锲入心灵的文字.与高人交心,轻松学习,把时间留给更重要的人更重要的事. 精彩就点击右上角分享出去,赠人玫瑰手染余香. 重点短语 ...

  9. 专家库管理软件专家评审系统_专家系统2 0

    专家库管理软件专家评审系统 Are neural networks and deep learning the keys that will finally unlock the path to ar ...

  10. 面试改掉呃呃呃_呃...税

    面试改掉呃呃呃 I've been having tax form fun this week- but the forms are now safely in their brown envelop ...

最新文章

  1. Linux Kernel TCP/IP Stack — L7 Layer — 高性能网络 I/O 服务器模型
  2. Java 使用匿名内部类在方法内部定义并启动线程
  3. 《快活帮》第九次团队作业:Beta冲刺与验收准备
  4. 第一阶段SCRUM冲刺 03
  5. Node.js与Express4安装与配置
  6. 收集sqlite常见问题
  7. c语言作业请输入一个运算符,C语言书面作业1(有答案版)..doc
  8. LeetCode 1367. 二叉树中的列表(双重递归)
  9. 如何给网页标题添加icon小图标
  10. LG深化与苹果合作,扩大向苹果供应OLED
  11. Fliptile 翻格子游戏[Usaco2007 Open]
  12. java包装_Java罐密封包装
  13. Impala ODBC 安装笔记
  14. Newton迭代法求无约束目标函数极小值matlab实现
  15. Linux安装libmodbus库
  16. c语言中内存分配方式
  17. oracle 字段名中有空格 的查询
  18. A Density-Based Algorithmfor Discovering Clusters in LargeSpatial Databaseswith Noise(KDD-96)
  19. linux下录音识别成文字软件下载,录音转文字分享助手
  20. unplugin-auto-import自动导入

热门文章

  1. 国产化性能最高的服务器,盘点服务器国产化呼声背后的优秀厂商
  2. 我的阿里面试经验分享给大家
  3. 一台服务器​最大并发 tcp 连接数多少?65535?
  4. Data Base学习记录:关系模型
  5. Android监听蓝牙与设备连接状态、关闭和打开状态
  6. Gensim的维基百科语料库中文词向量训练错误整理
  7. Fixed-step size(Solver)、Sample time(模块)、Sample time(powergui)三者的辨析
  8. var_threshold
  9. 【编译原理】实验二 词法分析程序
  10. 电路分析题目详解(四)