PTA 甲级 1012 The Best Rank

我的思路是:结构体排序+二分查找

值得注意的是:1.名次的算法 如 99、 99 、98 对应的排名是1 、1、3; 2.选取的是个人的最佳排名;3.排序函数,参考别人的写法还可以这样写,减少代码量

struct Stu{
    int id;
    int score[4];//a,c,m,e
    int rk[4];
};
//全局变量pos,迭代pos控制对那门课进行排序
bool cmp1(Stu&a, Stu& b) {
    return a.score[pos] > b.score[pos];
}

#include<iostream>
#include<algorithm>
#include<string>
#include<cmath>
#define MAXN 2010
using namespace std;

struct Stu{
    int id;
    int c,m,e,a;
    int c_rank,m_rank,e_rank,a_rank;
};
struct Stu stu[MAXN];
bool cmp(Stu&a,Stu&b){
    return a.id<b.id;
}
bool cmp0(Stu&a,Stu&b){
    return a.a>b.a;
}
bool cmp1(Stu&a,Stu&b){
    return a.c>b.c;
}
bool cmp2(Stu&a,Stu&b){
    return a.m>b.m;
}
bool cmp3(Stu&a,Stu&b){
    return a.e>b.e;
}

void work(Stu&s){
    string dis="ACME";
    int pos=0,rk=s.a_rank;
    if(s.c_rank<rk){
        rk=s.c_rank;
        pos=1;
    }
    if(s.m_rank<rk){
        rk=s.m_rank;
        pos=2;
    }
    if(s.e_rank<rk){
        rk=s.e_rank;
        pos=3;
    }
    cout<<rk<<" "<<dis[pos]<<endl;
}
int main(){
    int n,m;
    cin>>n>>m;
    for(int  i=0;i<n;i++){
        cin>>stu[i].id>>stu[i].c>>stu[i].m>>stu[i].e;
        stu[i].a=round(1.0*(stu[i].c+stu[i].m+stu[i].e)/3);
    }
    //排序
    sort(stu,stu+n,cmp0);
    for(int i=0,rk=1;i<n;i++){
        if(i==0){
            stu[i].a_rank=1;
        }
        else{
            if(stu[i].a<stu[i-1].a)rk=i+1;
            stu[i].a_rank=rk;
        }
    }
    sort(stu,stu+n,cmp1);
    for(int i=0,rk=1;i<n;i++){
        if(i==0){
            stu[i].c_rank=1;
        }
        else{
            if(stu[i].c<stu[i-1].c)rk=i+1;
            stu[i].c_rank=rk;
        }
    }
    sort(stu,stu+n,cmp2);
    for(int i=0,rk=1;i<n;i++){
        if(i==0){
            stu[i].m_rank=1;
        }
        else{
            if(stu[i].m<stu[i-1].m)rk=i+1;
            stu[i].m_rank=rk;
        }
    }
    sort(stu,stu+n,cmp3);
    for(int i=0,rk=1;i<n;i++){
        if(i==0){
            stu[i].e_rank=1;
        }
        else{
            if(stu[i].e<stu[i-1].e)rk=i+1;
            stu[i].e_rank=rk;
        }
    }
    //对id排序以便查找
    sort(stu,stu+n,cmp);
    // cout<<stu[0].id<<" "<<stu[1].id<<endl;
    for(int i=0;i<m;i++){
        int id;
        cin>>id;
        //二分查找
        int left=0,right=n-1;
        while(left<right){
            int mid=(left+right)/2;
            if(stu[mid].id<id) left=mid+1;
            else right=mid;
        }
        // printf("left=%d,stu[left].id=%d,id=%d\n",left,stu[left].id,id);
        if(stu[left].id!=id) cout<<"N/A"<<endl;
        
        else work(stu[left]);
    }
    return 0;
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值