批改多选题是比较麻烦的事情,有很多不同的计分方法。有一种最常见的计分方法是:如果考生选择了部分正确选项,并且没有选择任何错误选项,则得到 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,题目数目为M
char 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;
}