【PAT乙级】1058 选择题

    科技2024-12-17  10

    题目链接: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 << ' '; } }

     

    Processed: 0.017, SQL: 8