学习C++从娃娃抓起!记录下在学而思小猴编程学习过程中的题目,记录每一个瞬间。侵权即删,谢谢支持!
附上汇总贴:小猴编程C++ | 汇总-CSDN博客
【题目描述】
小猴在X学校的信息学集训队,集训队最近组织了一次能力评估测试——千分考,测试一共进行三天,每天进行一次测试,每天测试都有一个成绩。有
n
n
n 名同学参加了本次评估,编号依次为
1
∼
n
1\sim n
1∼n。
现在评估已经结束了,因为是OI赛制,所以H老师想让小猴统计一下每个同学的分数。小猴首先将每个同学在本次评估中每天的成绩录入到成绩管理系统中,系统会自动计算出每个同学三天成绩的总分。然后大家就可以在系统中查询到自己的得分情况。
成绩管理系统的功能如下:
- 成绩管理系统是按照每个同学的编号区分每个同学;
- 分别输入某个同学三天的成绩,可以自动计算出该同学的总成绩;
- 输入同学的编号后,可以重新输入该同学的三天的成绩,并且该同学之前的成绩作废;
- 输入同学的编号后,可以查看该同学的三天的成绩和总分;
- 可以根据同学们的总成绩从高到低排序,方便查询某一排名的同学的编号、三天的成绩以及总成绩。
小猴已经把所有人的成绩录入到系统中,因为是人工录入难免会有错误,所以小猴会根据同学们的反馈依次向成绩管理系统发出一些请求,请你根据不同的请求输出完成成绩管理系统做出对应的操作结果。
【输入】
第一行,包含一个整数
n
n
n,表示参加评估的学生人数;
接下来
n
n
n 行,每行包含三个非负整数
d
a
y
1
,
d
a
y
2
,
d
a
y
3
day1,day2,day3
day1,day2,day3,第
i
i
i 行依次表示编号为
i
i
i的同学的三天的成绩,
d
a
y
1
day1
day1 表示第一天的成绩,
d
a
y
2
day2
day2 表示第二天的成绩,
d
a
y
3
day3
day3 表示第三天的成绩;
接下来一行,包含一个正整数
q
q
q,表示小猴向成绩管理系统发出
q
q
q 次操作的请求;
接下来
q
q
q 行,每行第一个整数为
o
p
op
op,表示操作请求的类型:
- 若 o p = 1 op=1 op=1,表示需要修改某同学的成绩,需要输入一个正整数 x x x,表示该同学的编号,然后输入三个非负整数 d a y 1 , d a y 2 , d a y 3 day1,day2,day3 day1,day2,day3,分别表示该同学每天的成绩;
- 若 o p = 2 op=2 op=2,表示需要查询某同学的成绩,需要输入一个正整数 x x x,表示该同学的编号;
- 若 o p = 3 op=3 op=3,表示需要查询排名为第 r r r名同学的详细成绩信息,需要输入一个正整数 r r r,所有同学按总分从高到低排序,如果总分相同按编号从小到大排序。
【输出】
输出有若干行:
对于操作请求
o
p
=
2
op=2
op=2,输出一行四个整数,第一个整数表示该同学第一天的成绩,第二个整数表示该同学第二天的成绩,第三个整数表示该同学第三天的成绩,第四个整数表示该同学的总分。
对于操作请求
o
p
=
3
op=3
op=3,输出一行,表示排名为第
r
r
r名同学的详细成绩信息,包含五个整数, 第一个整数表示该同学的编号,第二个整数表示该同学第一天的成绩,第三个整数表示该同学第二天的成绩,第四个整数表示该同学第三天的成绩,第五个整数表示该同学的总分。
【输入样例】
5
88 59 52
85 3 82
18 67 22
1 41 98
76 75 68
2
1 1 85 32 73
3 1
【输出样例】
5 76 75 68 219
【代码详解】
#include <bits/stdc++.h>
using namespace std;
struct node {
int id, day1, day2, day3, s;
}a[8005];
int n, q, op, t[8005];
bool cmp(node x, node y)
{
if (x.s!=y.s) return x.s > y.s;
return x.id < y.id;
}
int main()
{
cin >> n;
for (int i=1; i<=n; i++) { // 输入n个人的成绩
cin >> a[i].day1 >> a[i].day2 >> a[i].day3;
a[i].s = a[i].day1 + a[i].day2 + a[i].day3;
a[i].id = i;
}
sort(a+1, a+n+1, cmp); // 先进行一次排序
for (int i=1; i<=n; i++) t[a[i].id] = i; // 使用t数组记录原始的id与排名的关系
cin >> q;
while (q--) { // 进行q次询问
cin >> op;
if (op==1) { // 对于操作1
int x;
cin >> x;
x = t[x];
cin >> a[x].day1 >> a[x].day2 >> a[x].day3;
a[x].s = a[x].day1+a[x].day2+a[x].day3; // 修改成绩
for (int i=x; i<n; i++) { // 修改成绩后按照总成绩重新排序,注意要总成绩相同时,编号小的在前面
if (a[i].s<a[i+1].s || (a[i].s==a[i+1].s && a[i].id > a[i+1].id)) swap(a[i],a[i+1]);
}
for (int i=x; i>1; i--) {
if (a[i].s>a[i-1].s || (a[i].s==a[i-1].s && a[i].id<a[i-1].id)) swap(a[i], a[i-1]);
}
for (int i=1; i<=n; i++) { // 再次刷新排名与id的关系
t[a[i].id] = i;
}
}
if (op==2) {
int x;
cin >> x; // 输入编号
x = t[x]; // 输入的是编号,找到对应的排名
cout << a[x].day1 << " " << a[x].day2 << " " << a[x].day3 << " " << a[x].s << endl;
}
if (op==3) {
int r;
cin >> r; // 输入排名(在op==1时已经重新按照总成绩大小排序)
cout << a[r].id << " " << a[r].day1 << " " << a[r].day2 << " " << a[r].day3 << " " << a[r].s << endl;
}
}
return 0;
}
【运行结果】
5
88 59 52
85 3 82
18 67 22
1 41 98
76 75 68
2
1 1 85 32 73
3 1
5 76 75 68 219