舞蹈课(dancingLessons)

Posted adelalove

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了舞蹈课(dancingLessons)相关的知识,希望对你有一定的参考价值。

技术分享图片
有n个人参加一个舞蹈课。每个人的舞蹈技术由整数ai来决定。在舞蹈课的开始,他们从左到右站成一排。当这一排中至少有一对相邻的异性时,舞蹈技术相差最小的那一对会出列并开始跳舞。如果相差最小的不止一对,那么最左边的那一对出列。一对异性出列之后,队伍中的空白按原顺序补上(即:若队伍为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
问题描述

解:50%的做法,直接模拟就可以了

正解:乱搞

想办法将模拟过程优化

主要分为两个优化,

1)将找最小值部分优化,

将所需信息用结构体记录下来,

用优先队列按照题目要求排序

2)将相邻两个人之间的关系用链表维护,

这样在出队时的关系维护可以做到O(1)

剩下的细节自己想(看代码)。

技术分享图片
 1 #include<algorithm>
 2 #include<iostream>
 3 #include<cstring>
 4 #include<cstdio>
 5 #include<string>
 6 #include<queue>
 7 #include<cmath>
 8 using namespace std;
 9 const int N=2e5+1000;
10 struct node{
11     int c,l,r;
12     bool operator < (const node &x) const{
13      if(c!=x.c) return c>x.c;
14      else return l>x.l;
15     }
16 }e[N],g[N];
17 priority_queue<node>q;
18 int n,a[N],L[N],R[N];
19 int k,qc,ql,qr;
20 bool v[N];
21 char s[N];
22 bool ok(int x){return (x>=1 && x<=n);}
23 int main()
24 {
25     freopen("dancingLessons.in","r",stdin);
26     freopen("dancingLessons.out","w",stdout);
27     scanf("%d",&n);scanf("%s",s+1);
28     for(int i=1;i<=n;++i) 
29     {
30         scanf("%d",&a[i]);
31         L[i]=i-1;R[i]=i+1;
32     }
33     for(int i=2;i<=n;++i)
34      if(s[i]!=s[i-1]) 
35       q.push((node){abs(a[i]-a[i-1]),i-1,i});
36     while(!q.empty())
37     {
38         qc=q.top().c;ql=q.top().l;
39         qr=q.top().r;
40         if(v[ql] || v[qr]) 
41         {
42             q.pop();continue;
43         }
44         v[ql]=v[qr]=1;
45         g[++k]=q.top();q.pop();
46         L[R[qr]]=L[ql];R[L[ql]]=R[qr];
47         if(ok(L[ql]) && ok(R[qr]))
48          if(s[L[ql]]!=s[R[qr]])
49           {
50              qc=abs(a[L[ql]]-a[R[qr]]);
51              ql=L[ql];qr=R[qr];
52 //              cout<<ql<<" "<<qr<<endl;
53              q.push((node){qc,ql,qr});
54          }
55     }
56     printf("%d\n",k);
57     for(int i=1;i<=k;++i)
58      printf("%d %d\n",g[i].l,g[i].r);
59     return 0;
60 }
View Code

 

以上是关于舞蹈课(dancingLessons)的主要内容,如果未能解决你的问题,请参考以下文章

洛谷 P1878 舞蹈课

洛谷P1878 舞蹈课 贪心 堆

ZOJ 3209 Treasure Map(舞蹈链)

使用改良版多值覆盖Dancing link X (舞蹈链)求解aquarium游戏

在课程的最后

Android使用片段在viewpager中的页面滚动上放置动画