1056. Mice and Rice (25)

点击打开链接

终于过了!!!

注意

1.题意首先没读懂,这题后面给的order是其id,意思是order中下标是顺序,内容是id

2.我的思路是建立一个胜者树,不断更新rank,因此就是要记录每次进入下一层的id,

而不是结构体本身,因为这样才能修改结构体中的rank

3.对于最后的输出,要记录下每一层的个数用lay[],然后按照个数更新rank

感觉更新rank的过程太复杂了,应该还有更好的方法

4.输出按照id顺序输出

#include <vector>
#include <cstdio>
#include <algorithm>
#include <string.h>
#define MAX 1010
using namespace std;
struct s {
    int w;
    int rank;
    int id;
}rec[MAX];
int np,ng;
int lay[MAX];
int ord[MAX];
int tmp[MAX];
bool cmp(int a,int b){
    return rec[a].w>rec[b].w;
}
bool fin(s a,s b){
    if(a.rank!=b.rank){
        return a.rank>b.rank;
    }else{
        return a.w>b.w;
    }
}
bool print(s a,s b){
    return a.id<b.id;
}
int main(){
    freopen("in.txt","r",stdin);
    scanf("%d %d",&np,&ng);
    for(int i=0;i<np;i++){
        scanf("%d",&rec[i].w);
        rec[i].id=i;
        rec[i].rank=0;
    }
    for(int i=0;i<np;i++){
        scanf("%d",&ord[i]);    
    }
    //本层的总数
    int cnt=np;
    //进入下一层的个数
    int qq=0;
    int layer=1;
    while(cnt!=1){
        for(int i=0;i<cnt;i+=ng){
            if(i+ng<cnt){
                sort(ord+i,ord+i+ng,cmp);    
            }else{
                sort(ord+i,ord+cnt,cmp);
            }
            //记录进入下一层的id
            tmp[qq++]=ord[i];
            rec[ord[i]].rank=layer;
            lay[layer]++;
        }
        //使ord记录进入下一层的id,因为始终对ord排序
        for(int i=0;i<qq;i++){
            ord[i]=tmp[i];
        }
        cnt=qq;
        qq=0;
        layer++;    
    }
    //修正layer
    int sum=lay[--layer];
    for(int i=layer-1;i>0;i--){
        lay[i]-=sum;
        sum+=lay[i];
    }
    lay[0]=np-sum;
    sort(rec,rec+np,fin);
    //根据lay中记录的每层的数量,重新更新rank
    int r=1;
    int cnr=0;
    for(int i=0;i<np;i++){
        rec[i].rank=r;
        cnr++;
        if(cnr==lay[layer]){
            r=r+cnr;
            cnr=0;
            layer--;
        }
    }
    //根据id输出
    sort(rec,rec+np,print);
    for(int i=0;i<np;i++){
        if(i+1==np){
            printf("%d\n",rec[i].rank);
        }else{
            printf("%d ",rec[i].rank);
        }
        
    }
    return 0;

}



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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值