开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第11天,点击查看活动详情
[传智杯 #2 初赛] 软件工程实习
题目描述
某大学的《软件工程》必修课分为理论和实践部分。理论部分由该校教授完成授课;而实践部分是由第三方的公司主导,需要同学们在五周时间内自学 HTML、css、JavaScript、vue、Python、django 等技术,并组队完成一个真实的互联网商业应用。
参与这个课程的有 个学生,分成了不超过 个队伍,每个队伍用 A 到 Z 来表示。每个队伍都会完成一个项目,并以队伍为单位,给所有队伍(包括自己队伍)打分,范围是 到 的整数。
为了平息学生对这门课产生的出多问题的不满(比如工作量太大、时间过于紧张、考核方式不公平等),老师决定使用一种“看起来”很公平的方式来决定每组队伍的项目得分:
对于某个队伍,首先计算所有队伍(包括自己)给这个队伍评分的平均值,然后剔除掉和这个平均值差别超过 分的评分(保证不会出现所有的评分全部被剔除的情况),最后再对剩余的评分求平均值,四舍五入取整后作为这个队伍的项目得分。
对于每一个同学,我们已经得知他们的队伍代号和理论成绩(也是 到 分的整数)。这位同学的最后得分就是 的理论成绩加上 的所在队伍的项目得分,然后四舍五入取整。
现在老师想知道所有同学的分数排行。请按最后得分从高到低的顺序,输出每位同学的得分和他所在的队伍。
输入格式
第一行两个整数 和 ,分别表示学生数和队伍数。
接下来 行,每行一个整数 和一个大写字母 ,表示第 个选手的理论分数和队伍编号。保证队伍编号范围是从 A 开始后连续 个字母中的一个。
接下来 行,每行 个整数。其中第 行第 列的整数 表示第 个队伍给第 个队伍的评分,当 时,就是自评。
输出格式
输出 行表示答案,得分高的同学优先输出,得分相同时队伍编号较小的同学优先输出。对于每一行,先输出这位同学成绩,然后输出代表他的队伍编号的大写英文字母。
样例 #1
样例输入 #1
6 3
70 A
80 A
65 B
95 B
85 C
90 C
70 90 100
95 88 85
30 47 100
样例输出 #1
93 B
92 C
89 C
76 A
75 B
70 A
提示
A 组收到的分数分别是 ,其平均分为 ,则 被作为无效成绩剔除,因此 A 组的项目得分是 分。
B 组收到的分数分别是 ,其平均分为 ,则 被作为无效成绩剔除,因此 B 组的项目得分是 分。
C 组收到的分数分别是 ,其平均分为 ,没有打分被剔除,因此 C 组的项目得分是 分。
思路分析
- 模拟题,但是很多坑
- 第一次算平均值的时候,不能四舍五入,第二次计算的时候才四舍五入
- 最后计算单人总成绩的时候,也要四舍五入
- 要用到仿函数排序规则
代码展示
#include<iostream>
#include<algorithm>
#include<vector>
#include<cmath>
using namespace std;
typedef pair<int, char>PIC;
vector<PIC>v;
int a[30][30];
int b[30];
bool cmp(PIC& a, PIC& b) {
return a.first > b.first;
}
int main()
{
int n, k;
cin >> n >> k;
for (int i = 0; i < n; i++) {
int sorce;
char ch;
cin >> sorce >> ch;
v.push_back({ sorce,ch });
}
for (int i = 0; i < k; i++)
for (int j = 0; j < k; j++)
cin >> a[i][j];
for (int i = 0; i < k; i++) {
double sum = 0;
for (int j = 0; j < k; j++)
sum += a[j][i];
double averge = sum * 1.0 / k, count = k;
for (int j = 0; j < k; j++) {
if(abs(averge - a[j][i]) > 15) {
a[j][i] = 0;
count--;
}
}
sum = 0;
for (int j = 0; j < k; j++) {
if (a[j][i])sum += a[j][i];
}
b[i] = (int)round(sum * 1.0 / count);
}
for (int i = 0; i < n; i++)
v[i].first = (int)round(v[i].first * 0.6 + b[v[i].second - 'A'] * 0.4);
sort(v.begin(), v.end(), cmp);
for (int i = 0; i < n; i++)
cout << v[i].first << " " << v[i].second << endl;
return 0;
}
PS:这是一道模拟题,较为容易,但是太多坑了,大家要注意~