1025. PAT Ranking (25)

1025. PAT Ranking (25)

Programming Ability Test (PAT) is organized by the College of Computer Science and Technology of Zhejiang University. Each test is supposed to run simultaneously in several places, and the ranklists will be merged immediately after the test. Now it is your job to write a program to correctly merge all the ranklists and generate the final rank.

Input Specification:

Each input file contains one test case. For each case, the first line contains a positive number N (<=100), the number of test locations. Then N ranklists follow, each starts with a line containing a positive integer K (<=300), the number of testees, and then K lines containing the registration number (a 13-digit number) and the total score of each testee. All the numbers in a line are separated by a space.

Output Specification:

For each test case, first print in one line the total number of testees. Then print the final ranklist in the following format:

registration_number final_rank location_number local_rank

The locations are numbered from 1 to N. The output must be sorted in nondecreasing order of the final ranks. The testees with the same score must have the same rank, and the output must be sorted in nondecreasing order of their registration numbers.

Sample Input:

2
5
1234567890001 95
1234567890005 100
1234567890003 95
1234567890002 77
1234567890004 85
4
1234567890013 65
1234567890011 25
1234567890014 100
1234567890012 85

Sample Output:

9
1234567890005 1 1 1
1234567890014 1 2 1
1234567890001 3 1 2
1234567890003 3 1 2
1234567890004 5 1 4
1234567890012 5 2 2
1234567890002 7 1 5
1234567890013 8 2 3
1234567890011 9 2 4

题目大意:

给pat考生排名,输入第一个为考场数,对于每一个考场,给定考生人数,每个考生有考号和成绩。输出所有考生的排名,格式为: 考生号 最终排名 考场号 考场排名。注意相同分数的考生名次相同,输出时按考号字典序从小到大排列

思路:

对stl中的sort函数进行重载比较函数来排序。先对每一个考场内的考生进行排序,得到考场排名,只有再对全部考生排序,得到最终排名

想法一
#include<bits/stdc++.h>
using namespace std;

struct node
{
    string s;//s为考号
    int num,frk,lrk,ln;//num为分数,frk为最终排名,lrk为考场排名,ln为考场号
} a[300+5],all[30000+5];//a为对考场内排序时使用的,all为全部考生信息

//sort的比较函数
int cmp(node n,node m)
{
    if(n.num==m.num) return n.s<m.s;//  分数相同比较考号
    else return n.num>m.num;//取分数大的
}

int main()
{
    int _,n,i,cnt=0,k,rk;//cnt记录考生数量,确定排名时用的
    scanf("%d",&_);
    for(k=1; k<=_; k++)
    {
        scanf("%d",&n);//考场内总人数
        for(i=0; i<n; i++)
        {
            cin>>a[i].s>>a[i].num;
            a[i].ln=k;//记录考生考场号
        }
        sort(a,a+n,cmp);//排序
        rk=1;
        //统计排名
        for(i=0; i<n; i++)
        {
            if(i>=1)
            {
                if(a[i].num==a[i-1].num)
                    a[i].lrk=a[i-1].lrk;//与前一个分数相同,排名相同
                else a[i].lrk=rk;
            }
            else a[i].lrk=rk;
            rk++;
        }
        //将a合并到all中
        for(i=0;i<n;i++)
        {
            all[cnt]=a[i];
            cnt++;
        }
    }
    sort(all,all+cnt,cmp);//排序
    //统计排名
    rk=1;
    for(i=0; i<cnt; i++)
    {
        if(i>=1)
        {
            if(all[i].num==all[i-1].num)
                all[i].frk=all[i-1].frk;
            else all[i].frk=rk;
        }
        else all[i].frk=rk;
        rk++;
    }
    //输出
    printf("%d\n",cnt);
    for(i=0; i<cnt; i++)
    {
        cout<<all[i].s<<" "<<all[i].frk<<" "<<all[i].ln<<" "<<all[i].lrk<<endl;
    }
    return 0;
}
想法二
#include<bits/stdc++.h>
using namespace std;

struct node
{
    string s;//s为考号
    int num,frk,lrk,ln;//num为分数,frk为最终排名,lrk为考场排名,ln为考场号
} all[30000+5];//all为全部考生信息

//sort的比较函数
int cmp(node n,node m)
{
    if(n.num==m.num) return n.s<m.s;//  分数相同比较考号
    else return n.num>m.num;//取分数大的
}

int r[30000+5],now[30000+5];//r维护当前考场前一名的编号,now记录当前考场的排名

int main()
{
    int _,n,i,cnt=0,k,rk,tmp;//cnt记录考生数量,确定排名时用的
    scanf("%d",&_);
    for(k=1; k<=_; k++)
    {
        scanf("%d",&n);//考场内总人数
        for(i=0; i<n; i++)
        {
            cin>>all[cnt].s>>all[cnt].num;
            all[cnt].ln=k;//记录考生考场号
            cnt++;
        }
    }
    memset(r,0xff,sizeof(r));//初始r为-1
    sort(all,all+cnt,cmp);//排序
    //统计排名
    rk=1;
    for(i=0; i<cnt; i++)
    {
        if(i>=1)
        {
            if(all[i].num==all[i-1].num)
                all[i].frk=all[i-1].frk;
            else all[i].frk=rk;
        }
        else all[i].frk=rk;
        //确定考场排名
        tmp=all[i].ln;
        if(r[tmp]==-1)//考场内第一人记为第一
        {
            all[i].lrk=1;
            now[tmp]=1;
        }
        else if(all[r[tmp]].num==all[i].num)//与前一名分数相同,排名相同
        {
            all[i].lrk=all[r[tmp]].lrk;
        }
        else
        {
            all[i].lrk=now[tmp];//分数不同时,获得新的排名
        }
        r[tmp]=i;//修改r
        now[tmp]++;//排名增加
        rk++;
    }
    //输出
    printf("%d\n",cnt);
    for(i=0; i<cnt; i++)
    {
        cout<<all[i].s<<" "<<all[i].frk<<" "<<all[i].ln<<" "<<all[i].lrk<<endl;
    }
    return 0;
}

提交结果

第一种想法

第二种想法

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值