【题目描述】:
有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;
}