题目要求
学生互评作业的简单规则是这样定的:每个人的作业会被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
代码以及解释
#include <iostream>
#include<bits/stdc++.h>
using namespace std;
//快排
int get_mid(double b[],int left,int right) //注意double数组
{
double pivot=b[left]; //同样要定义double类型的pivot存储数据
while(left<right)
{
while(b[right]>=pivot&&left<right) right--;
b[left]=b[right];
while(b[left]<=pivot&&left<right) left++;
b[right]=b[left];
}
b[left]=pivot;
return left;
}
void sqsort(double b[],int left,int right)
{
if(left<right)
{
int mid=get_mid(b,left,right);
sqsort(b,left,mid-1);
sqsort(b,mid+1,right);
}
}
int main()
{
int n,k,m;
cin>>n>>k>>m;
double num_suanfen[11];//用来算出一个同学的分数
double people_fenshu[10000];//存储每个人的分数,
//例如1同学分数为100:people_fenshu[1]=100;
double number; //暂时存储某一个同学的分数,用来做计算的中间变量
double max1,min1;//一个同学的成绩的最大值最小值
for(int i=1;i<=n;i++) //输入数据
{
number=0.00; //每次收入一个同学的成绩,number都要置零
int j=1;
while(cin>>num_suanfen[j]) //存入一个同学的成绩,注意while结束的条件
{
j++;
if(j>k)break;
}
max1=num_suanfen[1];//置初值
min1=num_suanfen[1];
for(int ii=1;ii<=k;ii++) //去掉最高分和最低分算出成绩
{
if(num_suanfen[ii]>max1) max1=num_suanfen[ii];
if(num_suanfen[ii]<min1) min1=num_suanfen[ii];
number+=num_suanfen[ii];
}
number=number-max1-min1;
people_fenshu[i]=number/(k-2);
}
sqsort(people_fenshu,1,n); //由高到低排序
int flag=1; //做标志,来满足“行首尾不得有多余空格”,判断是不是第一个数
for(int y=n-m+1;y<=n;y++)
{ if(flag==1)
{
printf("%.3f",people_fenshu[y]); //是第一个数,输出该数
flag++;//此时只要让flag不满足if条件就行
}
else //不是第一个数,输出空格和数字
printf(" %.3f",people_fenshu[y]);
}
return 0; //main函数结束
}
我是用的是快排,刚学,参考课本,需要注意的是因为要计算出来小数点后面数,所以有些地方用double类型(注释有写)。
思路是先计算出来每名学生的成绩(去掉了最高分和最低分之后的平均成绩),然后把这些同学的成绩进行非递减排序(如题意),然后输出后面m名同学的成绩。