• 模拟题 舞蹈课


    有n 个人参加一个舞蹈课。每个人的舞蹈技术由整数来决定。在舞蹈课的开始,他们从左到右站成一排。当这一排中至少有一对相邻的异性时,舞蹈技术相差最小的那一对会出列并开始跳舞。
    如果相差最小的不止一对,那么最左边的那一对出列。一对异性出列之后,队伍中的空白按原顺序补上(即:若队伍为ABCD,那么BC 出列之后队伍变为AD)。舞蹈技术相差最小即是的绝对值最小。 你的任务是,模拟以上过程,确定跳舞的配对及顺序。
    输入 第一行为正整数 :队伍中的人数。下一行包含 n 个字 符 B 或者 G,B 代表男,G 代表女。下一行为 n 个整数。所有信息按照从左到右的顺序给出。在
    50 的数据中,。 输出 第一行:出列的总对数k。接下来输出k 行,每行是两个整数。按跳舞顺序输出,两个整数代表这一对舞伴的编号(按输入顺序从左往右1 至n 编号)。请先输出较小的整数,再输出较大的整数。
    样例输入
    4 BGBG 4 2 4 3 样例输出 2 3 4 1 2 样例输入 4 BGBB 1 1 2 3 样例输出 1 1 2

      本来是做的一套题,但是T1和T3都好难qwq,就只剩下T2可做了。

      首先相邻男女的差值是可以用小根堆来维护的,但是而要求相邻的才可以跳舞,每次有出对的人后相邻的人又会发生变化,所以用链表来维护,然后就是一个细节问题,题面要求如果有多对相邻的男女并且他们的差值也一样的时候左边的男女优先出列,蒟蒻一开始没有处理这个,就挂了5组。

    代码:

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<queue>
     4 #include<cmath>
     5 using namespace std;
     6 const int maxn=200005;
     7 bool b[maxn];
     8 char c;
     9 int n;
    10 int L[maxn],R[maxn];
    11 struct zhw{
    12     int x,y;
    13     int d;
    14     bool operator <(const zhw &a)const
    15     {
    16         return d>a.d||(d==a.d&&min(x,y)>min(a.x,a.y));//差值是第一关键字,位置是第二关键字 
    17     }
    18 };
    19 priority_queue<zhw>q; 
    20 int v[maxn]; 
    21 int ans1[maxn],ans2[maxn]; 
    22 int tot;
    23 bool vis[maxn];
    24 int main()
    25 {
    26     scanf("%d",&n);
    27     for(int i=1;i<=n;++i)
    28     {
    29         cin>>c;
    30         b[i]= c=='B' ? 0:1;    
    31         L[i]=i-1,R[i]=i+1;
    32     }
    33     for(int i=1;i<=n;++i)scanf("%d",&v[i]);
    34     for(int i=1;i<=n;++i)
    35     {
    36         if(L[i]>=1&&b[i]!=b[L[i]])q.push((zhw){L[i],i,abs(v[i]-v[L[i]])});
    37     }
    38     while(!q.empty())
    39     {
    40         int k1=q.top().x,k2=q.top().y;
    41         q.pop();
    42         if(vis[k1]||vis[k2])continue;
    43         if(k1<1||k2>n||k1>n||k2<1)continue;
    44         vis[k1]=1,vis[k2]=1;
    45         ans1[++tot]=k1,ans2[tot]=k2;
    46 //        R[L[k1]]=R[k2],L[R[k2]]=L[k1];一开始写的时候直接这么赋的,但这样是不对的,因为可能k1的左边已经出去了,右边也一样,
    47 //这样会使得原本可以相邻的人相邻不到 
    48         int aaa,bbb;
    49         aaa=R[k2],bbb=L[k1];
    50         while(vis[aaa]&&aaa<=n&&aaa>=1)aaa=R[aaa];//一直找到没有出去的那个 
    51         while(vis[bbb]&&bbb>=1&&bbb<=n)bbb=L[bbb];
    52         L[aaa]=bbb,R[bbb]=aaa; 
    53         if(b[aaa]!=b[bbb])q.push((zhw){aaa,bbb,abs(v[aaa]-v[bbb])});
    54     }
    55     printf("%d
    ",tot);
    56     for(int i=1;i<=tot;++i)
    57         printf("%d %d
    ",min(ans1[i],ans2[i]),max(ans1[i],ans2[i]));
    58     return 0;
    59 }
    60 /*
    61 4
    62 BGBG
    63 4 2 4 3
    64 */
    View Code
  • 相关阅读:
    绝对差不超过限制的最长连续子数组
    单调栈的认识及其应用
    寻找两个正序数组的中位数寻找两个正序数组的中位数
    JVM垃圾回收机制和python的垃圾回收
    K 个不同整数的子数组
    python中闭包
    2021/2/8_ 最长湍流子数组
    python中的函数
    python中可变类型与不可变类型 + 类型转换
    python的元组
  • 原文地址:https://www.cnblogs.com/yuelian/p/9101683.html
Copyright © 2020-2023  润新知