舞蹈课

★实验任务

有 n 个人参加舞蹈课,每个人以他的舞蹈技能 ai 为特点。舞蹈课开始前,他们从左到右排成一行。当队伍中至少含有一名男生和一名女生时,下面的过程会重复进行:站在相邻位置的男女生且舞蹈技能差异最小的开始跳舞。如果有很多对,最靠左边的开始跳舞。跳舞完以后就离开。舞蹈技能的差异为| ai-aj| 。你的任务是找到每一对,并找出是按什么顺序开始跳舞。



★数据输入

输入的第 1 行是一个正整数 n(1 <= n <= 2 * 10^5) ,表示人的个数。第 2 行包含 n 个字符” B” 或” G” ,分别代表男生和女生,之间没有用空格隔开。第 3 行包含 n 个整数 ai (1 ≤  ai ≤  10^7) 表示每个人的舞蹈技能。按从左到右的顺序排列。



★数据输出输出 k 对。接下去输出 k 行,每行包含 2 个整数,表示组成一对的男女生的序号。按从左到右从 1 到 n 开始排序。当一对舞者离开时不用重新排序。打印每一对时按递增打印。按跳舞的顺序打印。


输入示例 输出示例

4           2

BGBG        3 4

4 2 4 3     1 2

<span style="color:#000000;"> #include<iostream>   
  
using namespace std;  
  
struct DanceClass  
  
{  
      
    long int ability;  
      
    bool sex,sign;  
      
    DanceClass ()  
          
    {  
          
        sign=1;  
          
    };  
      
};   
  
struct delta  
  
{  
      
    long int dt,from,to;  
      
};  
  
void buildheap(delta*dl,long int n)  
  
{  
      
    long int dec,son;  
      
    bool ok;   
      
    for(dec=n/2+1;dec>=1;dec--)  
          
    {  
          
        dl[0]=dl[dec];   
          
        son=2*dec;  
          
        ok=1;  
          
        while(son<=n&&ok)  
              
        {  
              
            if(son<n&&(dl[son].dt>dl[son+1].dt||  
                  
                dl[son].dt==dl[son+1].dt&&dl[son].from>dl[son+1].from))son++;  
              
            if(dl[0].dt>dl[son].dt||dl[0].dt==dl[son].dt&&dl[0].from>dl[son].from)  
                  
            {  
                  
                dl[son/2]=dl[son];   
                  
                son*=2;  
                  
            }  
              
            else  
                  
                ok=0;  
              
        }  
          
        dl[son/2]=dl[0];   
          
    }  
      
}   
  
void improve(delta*dl,long int sail)  
  
{  
      
    long int father,son;  
      
    bool ok=1;  
      
    son=2;  
      
    father=1;  
      
    while(son<sail-1&&ok)  
          
    {  
          
        if(son<=sail-1&&(dl[son].dt>dl[son+1].dt||  
              
            dl[son].dt==dl[son+1].dt&&dl[son].from>dl[son+1].from))son++;  
          
        if(dl[sail].dt>dl[son].dt||dl[sail].dt==dl[son].dt&&dl[sail].from>dl[son].from)  
              
        {  
              
            dl[father]=dl[son];  
              
            father=son;  
              
            son*=2;   
              
        }  
          
        else  
              
            ok=0;  
          
    }  
      
    dl[father]=dl[sail];  
      
}  
  
long int rebuildheap(delta*dl,DanceClass*DC,long int sail,long int n)  
  
{  
      
    long int ff,tt;  
      
    ff=dl[1].from;  
      
    tt=dl[1].to;  
      
    DC[ff].sign=0;  
      
    DC[tt].sign=0;    
      
    while(ff>=0&&DC[ff].sign==0)  
          
        ff--;  
      
    while(tt<=n&&DC[tt].sign==0)  
          
        tt++;   
      
    if(ff>=0&&tt<=n&&DC[ff].sign&&DC[tt].sign&&DC[ff].sex!=DC[tt].sex)  
          
    {  
          
        sail++;  
          
        dl[sail].from=ff;  
          
        dl[sail].to=tt;  
          
        dl[sail].dt=DC[ff].ability-DC[tt].ability;  
          
        if(dl[sail].dt<0)dl[sail].dt=-dl[sail].dt;   
          
    }     
      
    improve(dl,sail);  
      
    sail--;   
      
    while(DC[dl[1].from].sign==0||DC[dl[1].to].sign==0)    
          
    {  
          
        improve(dl,sail);  
          
        sail--;  
          
    }  
      
    return sail;  
      
}   
  
int main()  
  
{  
      
    long int n,add,inc,total;    
      
    char c;  
      
    DanceClass*DC;  
      
    delta*dl;  
      
    scanf("%d",&n);  
      
    DC=new DanceClass [n];  
      
    dl=new delta[n];    
      
    c=getchar();  
      
    for(add=0,total=0;add<n;add++)  
          
    {  
          
        c=getchar();  
          
        if(c=='B')  
              
        {  
              
            DC[add].sex=1;  
              
            total++;  
              
        }  
          
        else   
              
            DC[add].sex=0;    
          
    }   
      
    c=getchar();  
      
    for(add=0,inc=1;add<n;add++)  
          
    {  
          
        scanf("%d",&DC[add].ability);  
          
        if(add>0&&DC[add-1].sex!=DC[add].sex)  
              
        {  
              
            dl[inc].dt=DC[add-1].ability-DC[add].ability;  
              
            dl[inc].from=add-1;  
              
            dl[inc].to=add;  
              
            if(dl[inc].dt<0)dl[inc].dt=-dl[inc].dt;    
              
            inc++;  
              
        }   
          
    }  
      
    buildheap(dl,inc-1);   
      
    if(total+total>n)  
          
        total=n-total;   
      
    printf("%d\n",total);   
      
    inc--;  
      
    n--;  
      
    while(total>0)  
          
    {  
          
        total--;  
          
        printf("%d %d\n",dl[1].from+1,dl[1].to+1);  
          
        if(total)  
              
            inc=rebuildheap(dl,DC,inc,n);     
          
    }  
      
      
      
    return 0;  
      
}  </span>


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值