题目 A1083 List Grades
-
题意
按成绩排序,然后按排序顺序输出在成绩范围内[grade1, grade2]
的学生信息。不存在的输出NONE
。 -
思路
这题和福布斯那题很像,主要就是写个cmp
排序函数,然后识别成绩范围输出。这里需要注意的就是没有的情况,需要输出NONE
(全大写)。 -
Code in C++
#include <cstdio>
#include <iostream>
#include <algorithm>
#define maxn 200
struct student {
char name[11];
char ID[11];
int grade;
}stu[maxn];
bool cmp(const student &a, const student &b) {
return a.grade > b.grade;
}
bool isValid(int grade, int grade1, int grade2) {
if (grade >= grade1 && grade <= grade2) return true;
else return false;
}
int main()
{
int n;
std::cin >> n;
for (int i = 0; i < n; ++i) {
scanf("%s %s %d", stu[i].name, stu[i].ID, &stu[i].grade);
}
int grade1, grade2;
std::cin >> grade1 >> grade2;
std::sort(stu, stu + n, cmp);
int count = 0;
for (int i = 0; i < n; ++i) {
if (isValid(stu[i].grade, grade1, grade2)) {
if (count != 0) std::cout << std::endl;
printf("%s %s", stu[i].name, stu[i].ID);
++count;
}
}
if (count == 0)
std::cout << "NONE";
return 0;
}
题目 A1080 Graduate Admission
-
题意
每个学生可以报m
个学校志愿,根据总成绩和考试成绩排序。从前往后录取。但是在有相同排名的情况下可以超出学校录取规定人数。最后输出每个学校的录取学生情况。没有的输出空行。 -
思路
这里主要实现了两个cmp
函数,一个是按总成绩和考试成绩排序,另一个是按录取学校编号和学生编号升序排序。然后就是也有相同排名的情况,不过条件变成两个条件。另外通过结构体cur_quota
实现相同排名可以超人数录取。count
记录已录取人数,index
记录上个录取学生的序号,这样可以判断在超人数的时候可不可以并列录取。这里总成绩我直接采取了求和没有除以2,因为不影响相对大小。 -
Code in C++
#include <cstdio>
#include <cstring>
#include <algorithm>
#define maxn 40001
int n, m, k;
int quota[101];
struct cur_quota {
int count = 0; // 记录已录取学生人数
int index = 0; // 记录最后一个录取学生的下标,便于比较是否存在同排名
}cur[101];
struct applicant {
int num;
int gradee;
int gradei;
int total;
int school[5];
int rank;
int admmit;
}apps[maxn];
bool cmp(const applicant &a, const applicant &b) {
if (a.total != b.total) return a.total > b.total;
else return a.gradee > b.gradee;
}
bool cmps(const applicant &a, const applicant &b) {
if (a.admmit != b.admmit) return a.admmit < b.admmit;
else return a.num < b.num;
}
void init()
{
for (int i = 0; i < n; ++i) {
apps[i].num = i;
apps[i].total = 0;
memset(apps[i].school, -1, sizeof(apps[i].school));
apps[i].rank = -1;
apps[i].admmit = 100; // 因为学校最大为100,在后面学校排序时没有录取的排在后面
}
}
int main()
{
scanf("%d %d %d", &n, &m, &k);
for (int i = 0; i < m; ++i) {
scanf("%d", "a[i]);
}
init();
for (int i = 0; i < n; ++i) {
scanf("%d %d", &apps[i].gradee, &apps[i].gradei);
apps[i].total = apps[i].gradee + apps[i].gradei;
for (int j = 0; j < k; ++j) {
scanf("%d", &apps[i].school[j]);
}
}
std::sort(apps, apps + n, cmp); // 按总成绩和gradee排序
int r = 0;
for (int i = 0; i < n; ++i) {
if (i > 0 && (apps[i].total != apps[i-1].total || apps[i].gradee != apps[i-1].gradee)) {
r = i;
}
apps[i].rank = r;
for (int j = 0; j < k; ++j) {
int num = apps[i].school[j];
// 人数已达上限并且不存在与已录取学生同排名的情况下,进行下一个选项判断
if (cur[num].count >= quota[num] && apps[(cur[num].index)].rank < apps[i].rank) {
continue;
} else {
apps[i].admmit = num;
++cur[num].count;
cur[num].index = i;
break;
}
}
}
std::sort(apps, apps + n, cmps); // 按学校和学生编号排序
int start = 0;
for (int i = 0; i < m; ++i) {
if (cur[i].count == 0) {
printf("\n");
} else {
printf("%d", apps[start].num);
for (int j = 1; j < cur[i].count; ++j) {
printf(" %d", apps[start + j].num);
}
start += cur[i].count; // 存储下一个学校输出的学生首编号
printf("\n");
}
}
return 0;
}
小结
感觉这几天刷的内容都差不多,根据不同的规定实现不同的cmp
函数。可能存在需要实现多个的情况,以及在实现完排序函数之后再加一些限制的情况。但总体来说没太大不同。