欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

成绩排序

程序员文章站 2024-03-21 19:51:04
...

成绩排序

问题描述

有 n 名学生,它们的学号分别是 1,2,…,n。这些学生都选修了邓老师的算法训练营、数据结构训练营这两门课程。学期结束了,所有学生的课程总评都已公布,所有总评分数都是 [0,100] 之间的整数。巧合的是,不存在两位同学,他们这两门课的成绩都完全相同。邓老师希望将这些所有的学生按这两门课程的总分进行降序排序,特别地,如果两位同学的总分相同,那邓老师希望把算法训练营得分更高的同学排在前面。由于上面提到的巧合,所以,这样排名就可以保证没有并列的同学了。邓老师将这个排序任务交给了他的助教。可是粗心的助教没有理解邓老师的要求,将所有学生按学号进行了排序。邓老师希望知道,助教的排序结果中,存在多少逆序对。如果对于两个学生 (i,j) 而言,i 被排在了 j 前面,并且i 本应被排在 j 的后面,我们就称 (i,j) 是一个逆序对。请你先帮邓老师把所有学生按正确的顺序进行排名,再告诉他助教的错误排名中逆序对的数目。

输入格式
第一行一个整数 n,表示学生的个数。
第 2 行到第 n+1 行,每行 2 个用空格隔开的非负整数,第 i+1 行的两个数依次表示学号为 i 的同学的算法训练营、数据结构训练营的总评成绩。
输出格式
输出包含 n+1 行。
前 n 行表示正确的排序结果,每行 4 个用空格隔开的整数,第 i 行的数依次表示排名为 i 的同学的学号、总分、算法训练营成绩、数据结构训练营成绩。
第 n+1 行一个整数,表示助教的错误排名中逆序对的数目。

样例输入
3
95 85
90 90
100 99
样例输出
3 199 100 99
1 180 95 85
2 180 90 90
2
样例解释
学号为 3 的同学总分为 199,是最高的,所以他应该排第一名。
学号为 1 的同学虽然总分与学号为 2 的同学一致,但是他的算法训练营成绩更高,所以在排名规则下更胜一筹。
原错误排名中的逆序对数目为 2 ,这些逆序对分别为 (1,3) 和 (2,3)。

#include <iostream>
#include <vector>
#include <queue>
using namespace std;

vector<int> getAnswer(int n, vector<int> A, vector<int> DS){
    vector<int> sum, id;
    vector<int> ans;
    for(int i = 0; i < n; ++i){
        id.push_back(i + 1);
        sum.push_back(A[i] + DS[i]);
    }
    int cnt = 0;
    for(int i = 0; i < n-1; ++i)//进行n-1轮比较
        for(int j = n - 1; j > 0; --j)
            if(sum[j-1] < sum[j] ||
               (sum[j-1] == sum[j] && A[j-1] < A[j])){
                swap(id[j-1], id[j]);
                swap(sum[j-1], sum[j]);
                swap(A[j-1], A[j]);
                swap(DS[j-1], DS[j]);
                ++cnt;
            }
    for(int i = 0; i < n; ++i){
        ans.push_back(id[i]);
        ans.push_back(sum[i]);
        ans.push_back(A[i]);
        ans.push_back(DS[i]);
    }
    ans.push_back(cnt);
    return ans;
}

int main() {
    int n;
    cin >> n;
    vector<int> A, DS;
    
    for(int i = 0; i < n; ++i){
        int a, ds;
        cin >> a >> ds;
        A.push_back(a);
        DS.push_back(ds);
    }
    vector<int> ans = getAnswer(n, A, DS);

    for(int i = 0; i < 4*n+1; ++i){
        cout << ans[i] << " ";
        if(i % 4 == 3) cout << endl;
    }
    cout << endl;
    return 0;
}