zoukankan      html  css  js  c++  java
  • 排序入门练习题7 分数线划定 题解

    题目出处:《信息学奥赛一本通》第二章上机练习5/ 洛谷P1068

    题目描述

    世博会志愿者的选拔工作正在 A 市如火如荼的进行。为了选拔最合适的人才,(A) 市对所有报名的选手进行了笔试,笔试分数达到面试分数线的选手方可进入面试。面试分数线根据计划录取人数的 (150%) 划定,即如果计划录取 (m) 名志愿者,则面试分数线为排名第 (m imes 150\%)(向下取整)名的选手的分数,而最终进入面试的选手为笔试成绩不低于面试分数线的所有选手。
    现在就请你编写程序划定面试分数线,并输出所有进入面试的选手的报名号和笔试成绩。

    输入格式

    第一行,两个整数 (n,m(5 ≤ n ≤ 5000,3 ≤ m ≤ n)) ,中间用一个空格隔开,其中 (n) 表示报名参加笔试的选手总数,(m) 表示计划录取的志愿者人数。输入数据保证 (m imes 150\%) 向下取整后小于等于 (n)

    第二行到第 (n+1) 行,每行包括两个整数,中间用一个空格隔开,分别是选手的报名号 (k(1000 ≤ k ≤ 9999)) 和该选手的笔试成绩 (s(1 ≤ s ≤ 100)) 。数据保证选手的报名号各不相同。

    输出格式

    第一行,有 (2) 个整数,用一个空格隔开,第一个整数表示面试分数线;第二个整数为进入面试的选手的实际人数。
    从第二行开始,每行包含 (2) 个整数,中间用一个空格隔开,分别表示进入面试的选手的报名号和笔试成绩,按照笔试成绩从高到低输出,如果成绩相同,则按报名号由小到大的顺序输出。

    样例输入

    6 3 
    1000 90 
    3239 88 
    2390 95 
    7231 84 
    1005 95 
    1001 88
    

    样例输出

    88 5 
    1005 95 
    2390 95 
    1000 90 
    1001 88 
    3239 88 
    

    题目分析

    首先定义一个名为 Node 的结构体(我一般习惯不知道怎么命名的情况下就用 Node 来表示结构体,之前都是用 Student 来表示结构体的原因是 "Student" 是 "学生" 的英文,但是志愿者的英文 "volunteer" 有点难拼,虽然他应该是中考词汇,但是这里我还是写 Node 吧,我们把主要精力放到题目的解决上,而不要像老师我一样纠结于结构体的命名囧),它包含选手的报名号 k 和笔试成绩 s ,同时我们在定义结构题的同时初始化结构体数组:

    struct Node {
        int k;  // 报名号
        int s;  // 成绩
    } a[5005];
    

    然后就是我们的比较函数,比较函数要按照分数从高到低,分数相同的情况下报名号从小到大排:

    bool cmp(Node a, Node b) {
        if (a.s != b.s) // 如果成绩不同
            return a.s > b.s;   // 按成绩从高到低排
        return a.k <b.k; // 否则,按报名号从小到大排
    }
    

    排完序后,我们只需要选取前 (m imes 150\%) 位之前这就可以了。
    面试的分数线就是排名第 (m imes 150\%) 的选手的成绩。
    实现代码如下:

    #include <bits/stdc++.h>
    using namespace std;
    struct Node {
        int k, s;  // 分别表示报名号和成绩
    } a[5005];
    int n, m;
    bool cmp(Node a, Node b) {
        if (a.s != b.s) // 如果成绩不同
            return a.s > b.s;   // 按成绩从高到低排
        return a.k <b.k; // 否则,按报名号从小到大排
    }
    int main() {
        cin >> n >> m;
        for (int i = 0; i < n; i ++)
            cin >> a[i].k >> a[i].s;
        sort(a, a+n, cmp);
        int line = a[m*3/2-1].s;    // line表示分数线
        int id = m*3/2-1;   // id对应最后录取的那个人的坐标
        while (id+1 < n && a[id+1].s == line) id ++;
        cout << line << " " << id+1 << endl; // 输出分数线及录取人数
        for (int i = 0; i <= id; i ++)  // 输出录取人的名单
            cout << a[i].k << " " << a[i].s << endl;
        return 0;
    }
    
  • 相关阅读:
    DC中为什么要用Uniquify?
    hdu 1596 find the safest road
    hdu2112 HDU Today
    hdu 2066 一个人的旅行
    poj 3026 Borg Maze
    poj 1979 Red and Black
    poj 1321 棋盘问题
    hdu 1010 Tempter of the Bone
    hdu 4861 Couple doubi
    codeforces584B Kolya and Tanya
  • 原文地址:https://www.cnblogs.com/zifeiynoip/p/11450517.html
Copyright © 2011-2022 走看看