批改多选题是比较麻烦的事情,本题就请你写个程序帮助老师批改多选题,并且指出哪道题错的人最多。
输入格式:
输入在第一行给出两个正整数 N(≤ 1000)和 M(≤ 100),分别是学生人数和多选题的个数。随后 M 行,每行顺次给出一道题的满分值(不超过 5 的正整数)、选项个数(不少于 2 且不超过 5 的正整数)、正确选项个数(不超过选项个数的正整数)、所有正确选项。注意每题的选项从小写英文字母 a 开始顺次排列。各项间以 1 个空格分隔。最后 N 行,每行给出一个学生的答题情况,其每题答案格式为 (选中的选项个数 选项1 ……),按题目顺序给出。注意:题目保证学生的答题情况是合法的,即不存在选中的选项数超过实际选项数的情况。
输出格式:
按照输入的顺序给出每个学生的得分,每个分数占一行。注意判题时只有选择全部正确才能得到该题的分数。最后一行输出错得最多的题目的错误次数和编号(题目按照输入的顺序从 1 开始编号)。如果有并列,则按编号递增顺序输出。数字间用空格分隔,行首尾不得有多余空格。如果所有题目都没有人错,则在最后一行输出 Too simple。
输入样例: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) (2 b d) (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) (2 b c) (4 a b c d)
输出样例:3
6
5
2 2 3 4
测试点1 所有学生答题正确,没有错题要输出"Too simple"
解题思路
1.题目本身不难,判断每个学生的答案与对应题号的答案是否即可,统计错题数量然后输出错题信息,我有点想太多了
2.写这个题的时候,假设了输入的学生答案的信息存在干扰
所以本题参照之前的PTA basic 1052.卖个萌 的 字符串截取 方法, 取出了所有的学生选择题的选项数, 每一个选项
AC后查了下别人的答案,我的这个做法太多余了,直接把正确答案字符串录入, 然后和学生的答案字符串比较就可以得出答题是否正确
3.说下我这个方法的思路,
创建 题目类(序号,错误次数,题目分数,选项个数,正确选项个数,正确选项数组)
通过格式化的输入,录入题目的信息
循环通过getline()获取每一个学生的答题信息
依次判断每个学生的答题情况
进入判题阶段, 先取出每个学生的每一道题 不包括括号的子串, 取出学生在该题目的选项个数,
如果不符合正确选项个数, 则该题目错误数量+1, 继续下一题,
如果选项个数正确, 继续取出学生在该题目下选项数组,和正确的选项数组比较, 相等则累加题目分数, 否则该题目错误数量+1, 继续下一题
判题阶段结束
取出最大错题数
如果没有错题输出"Too simple", 有错题 要输出最大错题数和最大错题数相同的题目序号
4.比较符合题目要求的做法
题目录入的时候,正确答案应该录入字符串"正确选项数 选项1 选项2 ...."
判题阶段,取出学生答题字符串里括号中的内容"答题选项数 选项1 选项2 ...." 和 题目正确答案的字符串 直接比较
不需要取出每一个字符
比较符合题目的AC版本
#include#include #include using namespace std;class question{public: int falseTime;//错误次数
int fullPt;//题目分数
string correctAnswer;//正确答案字符串
question()=default;
question(int ft,int fp,string ca)
:falseTime{ft},fullPt{fp},correctAnswer{ca}{};
};int main(){ int n,m;//n学生个数 m题目个数
int fullPt,maxOptNum,scour{0};
vector questions;
vector Answers; string str,tempstr;
cin >> n>>m; for(int i=0;i
cin >> fullPt >> maxOptNum;
cin.ignore();//忽略换行符和空格 getline(cin,str);
question newQ{0,fullPt,str};
questions.push_back(newQ);
} for(int i=0;i
Answers.push_back(str);
} for(int i=0;i
scour=0; int left{0},right{0},count{0};//分别是左括号位置,右括号位置 左括号开始到右括号之前的字符数量
int j=0;//当前题目序号
str=Answers[i]; while(left
if(str[left]=='('){//从'('开始取出答案字符串
right=left;//right从left开始判断
while(right
tempstr=str.substr(left+1,count-1);//取出答案字符串 // 从'('右边一个位置开始取值,此时count计算了'(' 但是还没有加入')' //因此count-1,就是两个括号中间的内容
if(tempstr==questions[j].correctAnswer){//答案字符串和题目的正确答案比较
scour+=questions[j].fullPt;
}else{
questions[j].falseTime++;
}
count=0;//count清零
j++;//到下一题
break;
}
count++;
right++;
}
}
left++;
}
cout<
}
scour=0;//清零 用于比较题目的错误数
for(int i=0;i
scour=questions[i].falseTime>scour?questions[i].falseTime:scour;
} if(scour){//有错题 输出错题信息
cout<
}
}else{
cout <
} return 0;
}
取出了每个学生每道题目答题信息的AC版本#include#include #include using namespace std;class question{public: int index;//问题序号
int falseTime;//错误次数
int fullPt;//题目分数
int maxOptNum;//选项个数
int correctOptNum;//正确选项个数
vector correctOpts;//正确选项
question()=default;
question(int i,int ft,int fp,int mon,int con,vectorco)
:index{i},falseTime{ft},fullPt{fp},maxOptNum{mon},correctOptNum{con},correctOpts{co}{};
};int getFirstNum(string str){ int res=-1; for(int i=0;i='1'&&str[i]<='5'){
res=static_cast(str[i])-static_cast('0'); break;
}
} return res;
}
vector getops(string str,int maxops){ int op;
vector ops(maxops,0); for(int i=0;i='a'&&str[i]<='e'){
op=static_cast(str[i])-static_cast('a');
ops[op]=1;
}
} return ops;
}int main(){ int n,m;//n学生个数 m题目个数
int fullPt,maxOptNum,correctOptNum,temp,scour{0},count{0}; vector tempOps;
vector questions;//所有问题集合
vector Answers;//学生答案集合 string str,tempstr; char c;
cin >> n>>m; for(int i=0;i
cin >> fullPt >> maxOptNum >> correctOptNum;
vector tempOps(maxOptNum,0); for(int j=0;j
cin >> c; if(c<='e'&&c>='a'){
temp=static_cast(c)-static_cast('a');
tempOps[temp]=1;
}
}
question newQ(i+1,0,fullPt,maxOptNum,correctOptNum,tempOps);
questions.push_back(newQ);
tempOps.clear();
}
cin.ignore(); for(int i=0;i
Answers.push_back(str);
} for(int i=0;i
scour=0; int left{0},right{0}; int j=0;//判断每一题答题情况
str=Answers[i]; while(left
right=left;//从left开始截取字符串
while(right
if(str[right]==')'){
tempstr=str.substr(left+1,count-1); // 从'('右边一个位置开始取值,此时count计算了'(' 但是还没有加入')' //因此count-1,就是两个括号中间的内容
int opNums=getFirstNum(tempstr);//考生选择的选项数
if(opNums!=questions[j].correctOptNum){//如果选项数不等于正确选项数 则错误
questions[j].falseTime++;
}else{//选项数正确 判断选项 是否符合 正确选项
if(getops(tempstr,questions[j].maxOptNum)!=questions[j].correctOpts){//不符合则错误
questions[j].falseTime++;
}else{//都通过则正确 累加题目分数
scour+=questions[j].fullPt;
}
}
count=0;
j++; break;
}
count++;
right++;
}
}
left++;
}
cout<
}
scour=0; for(int i=0;i
scour=questions[i].falseTime>scour?questions[i].falseTime:scour;
} if(scour){//有错题 输出错题信息
cout<
}
}else{
cout <
} return 0;
}