舞会
学校举行舞会啦,一共有N个人参加,所有人站成一排,从左开始编号,最左边的人编号为1,最右边的为N。每个人跳舞的熟练度我们用一个整数表示,第i个人的熟练度为Ai,每次熟练度最接近的一对相邻男女会出列跳舞,如果有多对那么最左边的那一对会先出列,请你给出出列跳舞的顺序。
输入
第一行一个整数N,第二行N个字符表示N个人的性别,‘1’表示男孩,‘0’表示女孩。第三行N个整数表示每人熟练度。
N<=200000.Ai<=10^7
输出
第一行一个整数k,表示一共出列k对人。
下面k行,第i行两个整数ai,bi(ai<bi),表示第i次出列的是编号为ai,bi的一对。
样例输入
4
1011
1 1 2 3
样例输出
1
1 2
#include<queue> #include<cstring> #include<iostream> using namespace std; int a[200010],b[200010],nxt[200010],las[200010],in[200010],x[200010],y[200010]; inline int abs(int x) { return x<0?-x:x; } struct node { int x,y,w; // const{return w==a.w?x>a.x:w>a.w;} }; bool operator < (node xx,node yy) { if ( xx.w==yy.w) //如果权值一样,按x从小到大 return xx.x>yy.x; else //按权值从小到大 return xx.w>yy.w; } priority_queue<node>q;//大根堆 int main() { int n; scanf("%d\n",&n); for(int i=1;i<=n;i++) { a[i]=getchar()-'0'; in[i]=1; } for(int i=1;i<=n;i++) scanf("%d",&b[i]); for(int i=1;i<=n;i++) nxt[i]=i+1,las[i]=i-1; for(int i=1;i<n;i++) if(a[i]!=a[i+1]) q.push((node){i,i+1,abs(b[i]-b[i+1])}); int tot=0; while(!q.empty()) { node t=q.top(); q.pop(); int xx=t.x,yy=t.y; if(!in[xx]||!in[yy]||a[xx]==a[yy]) //如果xx不在队列中,或者yy不在队列中,或者两者性别是一样的 continue; //否则记入答案中 x[++tot]=xx; y[tot]=yy; in[xx]=in[yy]=0;//出队列 //a....xx.yy...b //设a的后继为b,b的前驱为a xx=las[xx],yy=nxt[yy]; nxt[xx]=yy,las[yy]=xx; if(in[xx]&&in[yy]&&a[xx]!=a[yy]) q.push((node){xx,yy,abs(b[xx]-b[yy])}); } printf("%d\n",tot); for(int i=1;i<=tot;i++) printf("%d %d\n",x[i],y[i]); return 0; }