思路:利用结构体记录id和成绩,再利用排序得出每个人每门科目的rank,之后再分别对每个学生处理rank求得其最佳排名。
说明:具体实现很多都可以利用sort简化代码量,本人出于练习的目的未使用。
#include <iostream>
#include <algorithm>
using namespace std;
struct student {
int id;
int grade[4]; //记录每个人的成绩和均分(均分用总分代替)
int rank[4]; //rankof each course;
int best[2];// best[0]=best rank;best[1]=best course;
}stu[2010];
int main() {
int n, m; //n=学生总数 , m=查询次数
cin >> n >> m;
for (int i = 0; i < n; i++) { //输入学生信息
cin >> stu[i].id >> stu[i].grade[0] >> stu[i].grade[1] >> stu[i].grade[2];
int sum = 0;
for (int j = 0; j < 3; j++)
sum += stu[i].grade[j];
stu[i].grade[3] = sum;
}
//分别排出四门课的排名 用Sort应该更方便 作为练习我自己写了简单选择排序
for (int c = 0; c < 4; c++) { //c代表四门课程 一次循环排出一门课程的名次
for (int i = 0; i < n - 1; i++) {
int maxpos = i;
for (int j = i + 1; j < n; j++) {
if (stu[j].grade[c] > stu[maxpos].grade[c])
maxpos = j;
}
swap(stu[maxpos], stu[i]);
}
stu[0].rank[c] = 1; //排序完第一个学生即为第一名
for (int i = 1; i < n; i++) {
if (stu[i].grade[c] == stu[i - 1].grade[c])
stu[i].rank[c] = stu[i - 1].rank[c]; //成绩与前面相同则名次相同
else
stu[i].rank[c] = i + 1; //成绩与前面不同则名次等于位次
}
}
for (int i = 0; i < n; i++) { //筛选出每个人的最佳排名
int bestpos = 0; //bestpos记录最好课程是哪一门 0123分别代表 ACME
for (int j = 1; j <= 2; j++) {
if (stu[i].rank[j] < stu[i].rank[bestpos])
bestpos = j;
}
if (stu[i].rank[3] <= stu[i].rank[bestpos]) //A的权重最高 单独拿出来
bestpos = 3;
stu[i].best[0] = stu[i].rank[bestpos]; //将最好名次及对应科目分别存入best[0]、[1]
stu[i].best[1] = bestpos;
}
//将所有学生按照id排名 便于二分查找提高效率
for (int i = 0; i < n - 1; i++) {
int minpos = i;
for (int j = i + 1; j < n; j++) {
if (stu[j].id < stu[minpos].id)
minpos = j;
}
swap(stu[minpos], stu[i]);
}
//二分查找
for (int i = 0; i < m; i++) {
int ser, pos = -1; //pos记录位置 ser为待查学生id
cin >> ser;
int low = 0, high = n - 1;
while (low <= high) {
int mid = (low + high) / 2;
if (stu[mid].id == ser) {
pos = mid; break;
}
else if (stu[mid].id > ser)
high = mid - 1;
else
low = mid + 1;
}
if (pos != -1) {
cout << stu[pos].best[0] << " ";
switch (stu[pos].best[1])
{
case 0:cout << "C"; break;
case 1:cout << "M"; break;
case 2:cout << "E"; break;
case 3:cout << "A"; break;
default:break;
}
cout << endl;
}
else
cout << "N/A" << endl;
}
return 0;
}