题目A1062 Talent and Virtue
-
题意
五类人,按高低排序,内部按总分,德分降序,ID升序排序。
① 成绩有一门低于L
的不参与。
② 圣人,德才均>=H
。
③ 君子,德>=H
, 才<H
。
④ 愚人,德才均<H
,但德>
才。
⑤ 小人,其他 -
思路
结构体存储数据,设置类型属性,先按类型排序然后再按题目给的其他条件排序。不符合要求的不参与。 -
Code in C++
#include <iostream>
#include <algorithm>
#define maxn 100001
enum Rank{
NONE,
SMALLMAN,
FOOLMAN,
NOBLEMAN,
SAGE
};
struct info {
int ID;
int virGrade;
int talGrade;
int total = 0;
Rank type = NONE;
void print() {
std::cout << ID << " " << virGrade << " " << talGrade << std::endl;
}
} person[maxn];
bool cmp(info a, info b) {
if (a.type != b.type) return a.type > b.type;
else if (a.total != b.total) return a.total > b.total;
else if (a.virGrade != b. virGrade) return a.virGrade > b.virGrade;
else return a.ID < b.ID;
}
int main()
{
int N, L, H;
int count = 0;
std::cin >> N >> L >> H;
for (int i = 0; i < N; ++i) {
std::cin >> person[i].ID >> person[i].virGrade >> person[i].talGrade;
// 判断德才分情况
if (person[i].virGrade < L || person[i].talGrade < L) continue;
else if (person[i].virGrade >= H && person[i].talGrade >= H) person[i].type = SAGE;
else if (person[i].virGrade >= H && person[i].talGrade < H) person[i].type = NOBLEMAN;
else if (person[i].talGrade < H && person[i].virGrade < H && person[i].virGrade >= person[i].talGrade) person[i].type = FOOLMAN;
else person[i].type = SMALLMAN;
++count;
person[i].total = person[i].virGrade + person[i].talGrade;
}
// sort
std::sort(person, person + N, cmp);
std::cout << count << std::endl;
for (int i = 0; i < count; ++i) {
person[i].print();
}
return 0;
}
题目A1012 The Best Rank
-
题意
按查询ID输出每个学生A、C、M、E
优先级中最高的排名。 -
思路
针对每个分数进行排名,然后查询的时候去获取分数中最小的排名。为了方便处理,利用数组下标进行映射。Rank
数组下标映射为ID
,course
下标与grade
下标对应,映射为科目。
注意
:相同分数相同排名 -
Code in C++
#include <iostream>
#include <algorithm>
#include <cmath>
struct perf{
int ID;
int grade[4];
}stu[2001];
char course[4] = {'A', 'C', 'M', 'E'};
int Rank[1000000][4] = {0}; // 一维下标表示ID号,二维对应结构体中各成绩排名
int now; // 排名成绩下标
bool cmp (perf a, perf b) {
return a.grade[now] > b.grade[now];
}
int main()
{
int n, m;
std::cin >> n >> m;
// grade 0-3 对应course
for (int i = 0; i < n; ++i) {
std::cin >> stu[i].ID >> stu[i].grade[1] >> stu[i].grade[2] >> stu[i].grade[3];
stu[i].grade[0] = round((stu[i].grade[1] + stu[i].grade[2] + stu[i].grade[3]) / 3.0) + 0.5;
}
for (now = 0; now < 4; ++now) {
std::sort(stu, stu + n, cmp);
Rank[stu[0].ID][now] = 1;
for (int i = 1; i < n; ++i) {
if (stu[i].grade[now] == stu[i-1].grade[now]) { // 与前一个相同排名
Rank[stu[i].ID][now] = Rank[stu[i-1].ID][now];
} else {
Rank[stu[i].ID][now] = i + 1;
}
}
}
int query;
for (int i = 0; i < m; ++i) {
std::cin >> query;
if (Rank[query][0] == 0) {
std::cout << "N/A" << std::endl;
} else {
int k = 0; // 选出四个成绩中最小排名
for (int j = 1; j < 4; ++j) {
if (Rank[query][k] > Rank[query][j]) {
k = j;
}
}
std::cout << Rank[query][k] << " " << course[k] << std::endl;
}
}
return 0;
}
小结
if - else if
的简洁写法
if (person[i].virGrade < L || person[i].talGrade < L) continue;
else if (person[i].virGrade >= H && person[i].talGrade >= H) person[i].type = SAGE;
else if (person[i].virGrade >= H && person[i].talGrade < H) person[i].type = NOBLEMAN;
else if (person[i].talGrade < H && person[i].virGrade < H && person[i].virGrade >= person[i].talGrade) person[i].type = FOOLMAN;
- 映射方法的使用。第二题中 ID和科目的映射。