题目链接:1058 选择题
思路
这题才20分也太亏了,虽然不是很难也没啥坑但要解决的问题很多,体量很大,写了半天。
结构体管理题目,除了需输入的分数,选项数,正确选项数,正确选项外,增加题号,错误次数这些需要最终输出的数据。正确选项使用大小为5的数组保存,0-4表示a-e,数值0为错误选项,1为正确选项。学生输入比较复杂,有括号,有空格,格式不确定由输入数据控制,过于复杂,直接选择用getline将整行接收,再进行处理。此处注意因为使用过cin,内存中还有被cin选择无视的回车存在,需要使用getchar接收,否则getline可能会将这个回车当作一次输入而导致少一次输入。输入后识别通过找左括号的方法作为学生每道题开始的标志,其后一位即该学生提交的选项数,每个选项之间间隔固定两位。对学生输入的处理部分:
将学生每道题得分暂定为满分,发现以下条件即改为0分:
选择了不正确选项。提交选项数量与正确答案选项数量不同。使用零填充数组保存学生分数,每题结束后将本题得分加入数组。若本题为0分,则将该题的错次加1。批改完一名学生的所有题目后,将其总得分输出。错题输出部分:
使用sort结合cmp的方法对结构体按照先错次,后题号的顺序进行排序。统计错误次数最多的题有几题错次相同。若最高错次为0,输出题目要求的“Too Simple”,结束问题。否则输出最高错次,再输出前几位错次相同的题目序号,结束问题
代码
#include <iostream>
#include <algorithm>
using namespace std;
struct question{
int no, fu, on, ri, wr = 0, op[5] = {0};
};//题号,满分,,选项总数,正确选项数,选错次数,正确选项A-E
//排序:错误数大优先,相等则题号小靠前
int cmp(question q1,question q2){
if(q1.wr == q2.wr){
return q1.no < q2.no;
}
return q1.wr > q2.wr;
}
int main(){
int M, N ,a, b, d, count=1;
int score[1000] = {0};
char c;
string s;
cin >> N >> M;
question q[M];
for(int i=0;i<M;i++){
cin >> q[i].fu >> q[i].on >> q[i].ri;
q[i].no = i;
for(int j=0;j<q[i].ri;j++){
cin >> c;
q[i].op[c-'a'] = 1;
}
}
getchar();//吸收cin跳过的回车,防止getline少输入一行
for(int i=0;i<N;i++){//第i名学生
getline(cin,s);
d = 0;
for(int j=0;j<M;j++){//第j道题
while(s[d++]!='(');
a = s[d] - '0';//a输入选项数,即'('的下一位
b = q[j].fu;//b本题得分,暂定满分
for(int k=0;k<a;k++){//第k个选项
d += 2;//每两位输入一个选项
c = s[d];
if(!q[j].op[c-'a']) b = 0;//若选项不在正确选项中,置0
}
if(a != q[j].ri) b = 0;//若正确选项数量不同,置0
if(b == 0) q[j].wr++;//得分为0错误计数加1
else score[i] += b;
}
cout << score[i] << endl;
}
sort(q,q+M,cmp);
while(q[count-1].wr == q[count].wr) count++;
if(q[0].wr == 0){
cout << "Too simple" << endl;
return 0;
}
cout << q[0].wr << ' ';
for(int i=0;i<count;i++){
cout << q[i].no+1;
if(i!=count-1) cout << ' ';
}
}