PTA 7-4 互评成绩 (15分)

    技术2022-07-11  112

    题目描述: 学生互评作业的简单规则是这样定的:每个人的作业会被k个同学评审,得到k个成绩。系统需要去掉一个最高分和一个最低分,将剩下的分数取平均,就得到这个学生的最后成绩。本题就要求你编写这个互评系统的算分模块。

    输入格式: 输入第一行给出3个正整数N(3 < N ≤10^​4,学生总数)、k(3 ≤ k ≤ 10,每份作业的评审数)、M(≤ 20,需要输出的学生数)。随后N行,每行给出一份作业得到的k个评审成绩(在区间[0, 100]内),其间以空格分隔。

    输出格式: 按非递减顺序输出最后得分最高的M个成绩,保留小数点后3位。分数间有1个空格,行首尾不得有多余空格。

    输入样例:

    6 5 3 88 90 85 99 60 67 60 80 76 70 90 93 96 99 99 78 65 77 70 72 88 88 88 88 88 55 55 55 55 55

    输出样例:

    87.667 88.000 96.000

    思路:根据题目描述,只需要输出成绩前M个学生的成绩,所以采用堆排序

    我的代码:

    #include <stdio.h> void HeapSort(double score[10001], int n, int k);//堆排序 void HeapAdjust(double score[10001], int s, int m); void swap(double* m, double* n);//交换 int main() { int n, k, m, i,j,max,min,sum = 0,p,l = 1; double aver; double score[10001];//记录每个学生的平均成绩 scanf("%d %d %d", &n, &k, &m); for (i = 0; i < n;i++) { sum = 0; max = 0;min = 100; for (j = 0; j < k;j++) {//输入每个学生的互评成绩 scanf("%d", &p); sum += p; if (max < p) {//记录最大值 max = p; } if (min > p) {//记录最小值 min = p; } } score[l] = (sum - max - min) * 1.0 / (k - 2);//记录平均成绩 下标从1开始 总成绩减去最大、最小值在除以 k-2求得平均数 l++; } HeapSort(score, l-1, m);//堆排序,l-1为数组长度,m为排序的次数 for (i = l - m;i<l ;i++) {//输出 if(i!=l-1) printf("%.3f ", score[i]); if (i == l-1) printf("%.3f", score[i]); } return 0; } void HeapSort(double score[10001], int n,int k) { int i; for (i = n / 2;i > 0;i--) {//从数组长度的1/2开始调整堆 HeapAdjust(score, i, n); } for (i = n;i > n-k;i--) {//每次循环找到一个目前最大的数 swap(&score[i], &score[1]);//将最大的数与最后一位交换 HeapAdjust(score, 1, i - 1);//i-1为当前数组长度:因为去掉了一个最大数,所以减1 } } void HeapAdjust(double score[10001], int s, int m) {//调整堆 double tem; int j; tem = score[s]; for (j = 2 * s;j <= m;j *= 2) {//s为j的父节点 if (j < m && score[j] < score[j + 1])//如果右孩子大于左孩子,则记录左孩子的下标 j++; if (tem >= score[j])//找到插入位置,则退出循环 break; score[s] = score[j];//未找到插入位置,继续往下一层遍历 s = j; } score[s] = tem;//插入数据 } void swap(double* m, double* n) { double tem = *m; *m = *n; *n = tem; }
    Processed: 0.025, SQL: 9