#71. 舞蹈课

【题目描述】:

有n个人参加一个舞蹈课。每个人的舞蹈技术由整数 来决定。在舞蹈课的开始,他们从左到右站成一排。当这一排中至少有一对相邻的异性时,舞蹈技术相差最小的那一对会出列并开始跳舞。如果相差最小的不止一对,那么最左边的那一对出列。一对异性出列之后,队伍中的空白按原顺序补上(即:若队伍为ABCD,那么BC出列之后队伍变为AD)。舞蹈技术相差最小即是 的绝对值最小。

你的任务是,模拟以上过程,确定跳舞的配对及顺序。

【输入描述】:

第一行为正整数n:队伍中的人数。下一行包含n个字符B或者G,B代表男,G代表女。下一行为n个整数ai 。所有信息按照从左到右的顺序给出。

【输出描述】:

第一行:出列的总对数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

【时间限制、数据范围及描述】:

时间:1s 空间:256M

对于 50%数据:n<=200

对于100%数据:1<=n<=2*10^5, ai<=10^7

#include<bits/stdc++.h>
#define M(a,b) memset(a,b,sizeof(a))
#define pi 3.1415926
using namespace std;
int n,i,a[200001],v[200001],num;
char s[200001];

struct Node{
    int x,y,w;
}e[200001];

bool operator >(Node A,Node B){
        if(A.w==B.w) return A.x>B.x;
        return A.w>B.w;
}

priority_queue<Node,vector<Node>,greater<Node> > q;

inline void push_(int x,int y){
    Node now;
    now.x=x;
    now.y=y;
    now.w=abs(a[x]-a[y]);
    q.push(now);
}

int main(){
	scanf("%d\n%s",&n,s);
    for(i=1;i<=n;i++)scanf("%d",&a[i]);
    for(i=1;i<=n-1;i++)if(s[i-1]!=s[i])push_(i,i+1);
    while(!q.empty()){
        Node now=q.top();
        q.pop();
        if(v[now.x]||v[now.y])continue;
        v[now.x]=1;v[now.y]=1;
        e[++num]=now;
        int l=now.x-1,r=now.y+1;
        if(l<1 || r>n) continue;
        while(l>1 && v[l])l--;
        while(r<n && v[r])r++;
        if(v[l] || v[r]) continue;
        if(s[l-1]!=s[r-1])push_(l,r);
    }
    printf("%d\n",num);
    for(i=1;i<=num;i++)printf("%d %d\n",e[i].x,e[i].y);
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值