题目
程序设计能力实训是华东师范大学计软院让学生非常头痛的一门课程,课程考试旨在通过统一组织的在线考试及自动评测方法客观地评判考生的算法设计与程序设计实现能力,每次考试会有多个考场同时进行考试,假设每个考场会在考试结束后产生一份学生成绩,之后将各个考场的成绩汇总为一份总的成绩单,现在请你对这张总的成绩单进行排名。
思路
实训,我的痛苦面具
需要注意的是,同分的同学排名一致。虽然输出时学号为第二关键字,但在赋排名时不能简单+1。
需要考虑遍历每个考场中的学生时数组越界的问题。
方法1
简单的做法是用库函数sort,由于二维数组行分布并不均匀,处理起来有点麻烦(其实是太菜处理不好),所以将排好序的二维数组拷贝进一个一维数组重新排序。
方法2
由于题目要求,已经排好了各小数组的顺序,考虑使用归并排序。
代码
方法1
#include<bits/stdc++.h>
using namespace std;
struct student
{
long long numStu; // 学号
int rankAll; // 所有人中的排名
int numTest; // 考场号
int rankLoc; // 本考场中的排名
int score = -1; // 分数
};
bool cmp1(student a, student b)
{
if (a.score != b.score)
return a.score > b.score;
else return a.numStu < b.numStu;
}
int main()
{
int n; cin >> n;
int allStu = 0;
student** a = new student * [n + 1];
int* tmpNumTest = new int[n + 1];
for (int i = 1; i <= n; i++)
// 考场号为i
{
int numTest; cin >> numTest;
allStu += numTest;
a[i] = new student[numTest];
tmpNumTest[i] = numTest;
for (int j = 0; j < numTest; j++)
{
a[i][j].numTest = i;
long long numStu;
int score;
cin >> numStu >> score;
a[i][j].numStu = numStu;
a[i][j].score = score;
}
sort(a[i], a[i] + numTest, cmp1);
//for (int j = 0; j < numTest; j++)
//{
// a[i][j].rankLoc = j + 1;
//}
a[i][0].rankLoc = 1;
int kk = 1;
int step = 1;
while (kk<numTest)
{
if (a[i][kk].score == a[i][kk - 1].score)
{
a[i][kk].rankLoc = a[i][kk - 1].rankLoc;
kk++;
step++;
}
else
{
a[i][kk].rankLoc = a[i][kk - 1].rankLoc + step;
kk++;
step = 1;
}
}
//cout << "*************" << endl;
//for (int j = 0; j < numTest; j++)
//{
// cout << a[i][j].numStu << ' ' << a[i][j].numTest << ' '<< a[i][j].rankLoc << endl;
//}
}
cout << allStu << endl;
student* res = new student[allStu + 1];
int idxRes = 0;
for (int i = 1; i <= n; i++)
{
for (int j = 0; j < tmpNumTest[i] && a[i][j].score != -1; j++)
{
res[idxRes].numStu = a[i][j].numStu;
res[idxRes].numTest = a[i][j].numTest;
res[idxRes].rankLoc = a[i][j].rankLoc;
res[idxRes].score = a[i][j].score;
idxRes++;
}
}
sort(res, res + allStu, cmp1);
res[0].rankAll = 1;
int ii = 1;
int sstep = 1;
while (ii < allStu)
{
if (res[ii].score == res[ii - 1].score)
{
res[ii].rankAll = res[ii - 1].rankAll;
sstep++;
}
else
{
res[ii].rankAll = res[ii - 1].rankAll + sstep;
sstep = 1;
}
ii++;
}
for (int i = 0; i < allStu; i++)
{
cout << res[i].numStu << ' ' << res[i].rankAll << ' ' << res[i].numTest << ' ' << res[i].rankLoc << endl;
}
return 0;
}
方法2
#include<bits/stdc++.h>
using namespace std;
#define K 300
struct student
{
long long numStu; // 学号
int rankAll; // 所有人中的排名
int numTest; // 考场号
int rankLoc; // 本考场中的排名
int score = -1; // 分数
};
bool cmp1(student a, student b)
{
if (a.score != b.score)
return a.score > b.score;
else return a.numStu < b.numStu;
}
int main()
{
int n; cin >> n;
int allStu = 0;
student** a = new student * [n + 1];
int* tmpNumTest = new int[n + 1];
for (int i = 1; i <= n; i++)
// 考场号为i
{
int numTest; cin >> numTest;
allStu += numTest;
a[i] = new student[K];
tmpNumTest[i] = numTest;
for (int j = 0; j < numTest; j++)
{
a[i][j].numTest = i;
long long numStu;
int score;
cin >> numStu >> score;
a[i][j].numStu = numStu;
a[i][j].score = score;
}
sort(a[i], a[i] + numTest, cmp1);
a[i][0].rankLoc = 1;
int kk = 1;
int step = 1;
while (kk < numTest)
{
if (a[i][kk].score == a[i][kk - 1].score)
{
a[i][kk].rankLoc = a[i][kk - 1].rankLoc;
kk++;
step++;
}
else
{
a[i][kk].rankLoc = a[i][kk - 1].rankLoc + step;
kk++;
step = 1;
}
}
//cout << "*************" << endl;
//for (int j = 0; j < numTest; j++)
//{
// cout << a[i][j].numStu << ' ' << a[i][j].numTest << ' '<< a[i][j].rankLoc << ' ' << a[i][j].score<<endl;
//}
}
cout << allStu << endl;
student* res = new student[allStu + 1];
int* head = new int[n+1];
memset(head, 0, sizeof(int) * (n + 1));
int idxRes = 0;
//int maxScore = 0;
//int maxIdx = 1;
while (idxRes<allStu)
{
int maxScore = 0;
int maxIdx = 1;
for (int i = 1; i <= n; i++)
// 遍历每一个考场
{
if (head[i] >= tmpNumTest[i]) continue; // 考虑数组越界问题
if (a[i][head[i]].score>maxScore || (a[i][head[i]].score==maxScore && a[i][head[i]].numStu<=a[maxIdx][head[maxIdx]].numStu))
{
maxScore = a[i][head[i]].score;
maxIdx = i;
}
}
res[idxRes].score = maxScore;
res[idxRes].numStu = a[maxIdx][head[maxIdx]].numStu;
res[idxRes].numTest = a[maxIdx][head[maxIdx]].numTest;
res[idxRes].rankLoc = a[maxIdx][head[maxIdx]].rankLoc;
head[maxIdx]++;
idxRes++;
maxIdx= maxIdx==1?maxIdx+1:maxIdx-1;
}
res[0].rankAll = 1;
int ii = 1;
int sstep = 1;
while (ii < allStu)
{
if (res[ii].score == res[ii - 1].score)
{
res[ii].rankAll = res[ii - 1].rankAll;
ii++;
sstep++;
}
else
{
res[ii].rankAll = res[ii - 1].rankAll + sstep;
ii++;
sstep = 1;
}
}
for (int i = 0; i < allStu; i++)
{
cout << res[i].numStu << ' ' <<res[i].rankAll<<' ' << res[i].numTest << ' ' << res[i].rankLoc << endl;
}
return 0;
}