【PAT甲级】刷题记录 1012


一、解答代码

#include <iostream>
using namespace std;
void rank_f(int sub,float** student_data,int** student_rank,int student_n);
int main()
{
    int student_n,check_n=0;   //学生数量。需要查找的学生数量
    cin>>student_n>>check_n;   //输入数据
    
    float** student_data=NULL; //创建相应的数组存放学生id,学生成绩,学生的排名
    string* student_id;
    int** student_rank;
    
    student_data=new float*[student_n];    //各数组的初始化工作
    student_id=new string[student_n];
    student_rank=new int*[student_n];
    
    for(int i=0;i<student_n;i++){
        student_data[i]=new float[4];
        student_rank[i]=new int[4];
        cin>>student_id[i];
        float total=0;
        for(int j=0;j<3;j++){
            cin>>student_data[i][j];
            student_rank[i][j]=-1;
            total=total+student_data[i][j];
        }
        student_data[i][3]=total/3;    //计算平均值
        student_rank[i][3]=-1;
    }
    for(int sub=0;sub<4;sub++){        //遍历各个科目,对成绩进行排名
        rank_f(sub,student_data,student_rank,student_n);//生成某一科各个id的排名
    }
    for(int i=0;i<check_n;i++){        //遍历输入id,查找该id的最优排名
        string check_id;
        cin>>check_id;
        int id_tag=-1;
        for(int j=0;j<student_n;j++){  //查找id对应的
            if(student_id[j]==check_id){
                id_tag=j;
                break;
            }
        }
        if(id_tag==-1){                //如果id不存在,直接输出“N/A”,跳过本轮循环
            cout<<"N/A"<<endl;
            continue;
        }
        int choose_sub=3;             //因为平均分优先级最高,将最优排名所选科目初始化为平均分代表的3
        for(int i=0;i<3;i++){         //按优先级依次降低的顺序,依次查看该id各科中的最优排名
            if(student_rank[id_tag][i]<student_rank[id_tag][choose_sub]){
            choose_sub=i;
            }
        }
        cout<<student_rank[id_tag][choose_sub]; //输出查找结果
        switch(choose_sub)                      //输出对应科目
        {
            case 0:
                cout<<" C";
                break;
            case 1:
                cout<<" M";
                break;
            case 2:
                cout<<" E";
                break;
            case 3:
                cout<<" A";
                break;
            default:
                break;
        }
        cout<<endl;
    }
    
    return 0;
}

void rank_f(int sub,float** student_data,int** student_rank,int student_n)  //生成某一科各个id的排名
{
    int record=-1;
    int record_rank=-1;
    for(int k=0;k<student_n-1;k++){              //k代表现在在寻找成绩第k+1位的id
        int max_stu=-1;
        for(int n=0;n<student_n-1;n++){          //找出目前还没有排名数据的最小数组下标
            if(student_rank[n][sub]==-1){
                max_stu=n;
                break;
            }
        }
        for(int m=max_stu+1;m<student_n;m++){     //从最小数组下标n之后开始遍历寻找寻找成绩第k+1位的id
            if((student_data[m][sub]>student_data[max_stu][sub])&&student_rank[m][sub]==-1){
                //每当遍历到分数更高且还没有排名数据的id时,更新成绩第k+1位的id
                max_stu=m;
            } 
        }
        //当第k+1位的id的成绩与记录下的之前排名的成绩一样时,使用相同排名
        //否则将将该id排名置为k+1,并更新成绩记录排名记录
        if(student_data[max_stu][sub]==record){
            student_rank[max_stu][sub]=record_rank;
        }else{
            record_rank=student_rank[max_stu][sub]=k+1;
            record=student_data[max_stu][sub];
        }
    }
    //对剩下最后一个没排名数据的id,将其排名置为学生人数,即最后一名
    for(int k=0;k<student_n;k++){
        if(student_rank[k][sub]==-1){
            student_rank[k][sub]=student_n;
        }
    }
    
}

二、坑点

参考以下链接:PAT——甲级1012:The Best Rank(有坑)

原文截图:
在这里插入图片描述
最后,新人发文,如有疏漏不足,还望各位指正!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值