当前位置: 代码迷 >> 综合 >> PAT 乙级 1073 多选题常见计分法
  详细解决方案

PAT 乙级 1073 多选题常见计分法

热度:68   发布时间:2023-12-28 03:01:05.0

批改多选题是比较麻烦的事情,有很多不同的计分方法。有一种最常见的计分方法是:如果考生选择了部分正确选项,并且没有选择任何错误选项,则得到 50% 分数;如果考生选择了任何一个错误的选项,则不能得分。本题就请你写个程序帮助老师批改多选题,并且指出哪道题的哪个选项错的人最多。

输入格式:

输入在第一行给出两个正整数 N(≤1000)和 M(≤100),分别是学生人数和多选题的个数。随后 M 行,每行顺次给出一道题的满分值(不超过 5 的正整数)、选项个数(不少于 2 且不超过 5 的正整数)、正确选项个数(不超过选项个数的正整数)、所有正确选项。注意每题的选项从小写英文字母 a 开始顺次排列。各项间以 1 个空格分隔。最后 N 行,每行给出一个学生的答题情况,其每题答案格式为 (选中的选项个数 选项1 ……),按题目顺序给出。注意:题目保证学生的答题情况是合法的,即不存在选中的选项数超过实际选项数的情况。

输出格式:

按照输入的顺序给出每个学生的得分,每个分数占一行,输出小数点后 1 位。最后输出错得最多的题目选项的信息,格式为:错误次数 题目编号(题目按照输入的顺序从1开始编号)-选项号。如果有并列,则每行一个选项,按题目编号递增顺序输出;再并列则按选项号递增顺序输出。行首尾不得有多余空格。如果所有题目都没有人错,则在最后一行输出 Too simple

输入样例 1:

3 4 
3 4 2 a c
2 5 1 b
5 3 2 b c
1 5 4 a b d e
(2 a c) (3 b d e) (2 a c) (3 a b e)
(2 a c) (1 b) (2 a b) (4 a b d e)
(2 b d) (1 e) (1 c) (4 a b c d)

输出样例 1:

3.5
6.0
2.5
2 2-e
2 3-a
2 3-b

输入样例 2:

2 2 
3 4 2 a c
2 5 1 b
(2 a c) (1 b)
(2 a c) (1 b)

输出样例 2:

5.0
5.0
Too simple

将做题情况与错题情况写入两个数组中,最后统计在两个数组之中进行,根据对应的映射来进行。值得注意的是:1.第39行进行判断的程序,一开始用一个单纯的else结果仅得两分,想了几个小时也没有结果,后决定将else if补完,使条件达到正确,结果便通过了 。2.少选的选项一开始没有考虑进错题中,觉得太麻烦,其实将其反映至对应的表中即可,无论是少选还是错选都要算错题 3.少选的分数如何计算,需要将少选的题全部选出,这里控制flag可以实现  4.关于多个最大值问题,存放到二维数组中,然后遍历数组即可(若数组量小可以这么做,本题在做的时候复杂化了,量大或者无法决定时可以考虑下二维指针)4.关于set和map,vector这三个容器还没有掌握,可能用于大容量数据的查重会有用。剩下还是先按照基本的一维二维数组来做。5.突然想到二维指针怎么用,在乙级1050中,二维指针的出现是用于无法确定大小的矩阵中,定义成m与n,因为在这题中矩阵的维数由计算得。

代码如下:

#include <bits/stdc++.h>using namespace std;struct grade
{double full;int na;int nr;//正确选项个数int zhengque[5]= {0}; //记录下每一题的正确选项
} gg[110];int b[110][5];//记录下做题的情况int d[110][5];//记录下错题的情况,需要用一个Int型矩阵表示int max=0;//max用于记录最大错题的数目double judge(int j)
{double fenshu=0;int flag=0;//进行判断int count0=0;//代表在1题中做对的选项for(int i=0; i<5; i++){if(gg[j].zhengque[i]!=b[j][i]){if(gg[j].zhengque[i]==1&&b[j][i]==0){d[j][i]++;}else if(gg[j].zhengque[i]==0&&b[j][i]==1){flag=1;d[j][i]++;//相当于出现了错选}}else if(gg[j].zhengque[i]==1&&b[j][i]==1){count0++;}}if(flag==1){fenshu=0;}else if(flag==0){if(count0<gg[j].nr){fenshu=0.5*gg[j].full;}else if(count0==gg[j].nr){fenshu=gg[j].full;}}return fenshu;
}//这个函数是对不同学生的每一道题进行判断,需要的最大值是错误最多的题目的选项,先记录下错误的情况int main()
{int N,M;cin>>N>>M;//输入学生人数与题目的数目,学生人数为N,题目数目为Mchar c;//输入字符,主要是应对选项的输入for(int i=0; i<M; i++){cin>>gg[i].full>>gg[i].na>>gg[i].nr;for(int j=0; j<gg[i].nr; j++){cin>>c;gg[i].zhengque[(int)c-(int)'a']=1;}}//可以每做一步便对结果进行输出的检验,思路一定要清晰int k=0;//控制每一个选项for(int i=0;i<M;i++){for(int j=0;j<5;j++){b[i][j]=0;d[i][j]=0;}}for(int i=0; i<N; i++){double sum=0;for(int ii=0;ii<M;ii++){for(int jj=0;jj<5;jj++){b[ii][jj]=0;}}for(int j=0; j<M; j++){cin>>c;//左括号cin>>k;for(int l=0; l<k; l++){cin>>c;//输入每个学生的选项b[j][(int)c-(int)'a']=1;}cin>>c;//为右括号//下面开始进行分数与错题的统计sum+=judge(j);}cout<<setiosflags(ios::fixed)<<setprecision(1)<<sum<<endl;}//输入每个学生的答题情况,输出其分数//在输出分数完成后需要进行错误题数的统计,也是最难的int max=d[0][0];int count=0;for(int i=0; i<M; i++){for(int j=0; j<5; j++){if(d[i][j]!=0){count++;}if(d[i][j]>max){max=d[i][j];}}}if(count!=0){for(int i=0; i<M; i++){for(int j=0; j<5; j++){if(d[i][j]==max){cout<<d[i][j]<<" "<<i+1<<"-"<<char('a'+j)<<endl;}}}}else if(count==0){cout<<"Too simple"<<endl;}return 0;
}