当前位置: 代码迷 >> 综合 >> 【PAT乙级】1058 选择题
  详细解决方案

【PAT乙级】1058 选择题

热度:13   发布时间:2024-02-25 18:44:36.0

题目链接:1058 选择题

思路

这题才20分也太亏了,虽然不是很难也没啥坑但要解决的问题很多,体量很大,写了半天。

  1. 结构体管理题目,除了需输入的分数,选项数,正确选项数,正确选项外,增加题号,错误次数这些需要最终输出的数据。正确选项使用大小为5的数组保存,0-4表示a-e,数值0为错误选项,1为正确选项。
  2. 学生输入比较复杂,有括号,有空格,格式不确定由输入数据控制,过于复杂,直接选择用getline将整行接收,再进行处理。此处注意因为使用过cin,内存中还有被cin选择无视的回车存在,需要使用getchar接收,否则getline可能会将这个回车当作一次输入而导致少一次输入。输入后识别通过找左括号的方法作为学生每道题开始的标志,其后一位即该学生提交的选项数,每个选项之间间隔固定两位。
  3. 对学生输入的处理部分:
    1. 将学生每道题得分暂定为满分,发现以下条件即改为0分:
      1. 选择了不正确选项。
      2. 提交选项数量与正确答案选项数量不同。
    2. 使用零填充数组保存学生分数,每题结束后将本题得分加入数组。若本题为0分,则将该题的错次加1。
    3. 批改完一名学生的所有题目后,将其总得分输出。
  4. 错题输出部分:
    1. 使用sort结合cmp的方法对结构体按照先错次,后题号的顺序进行排序。
    2. 统计错误次数最多的题有几题错次相同。
    3. 若最高错次为0,输出题目要求的“Too Simple”,结束问题。
    4. 否则输出最高错次,再输出前几位错次相同的题目序号,结束问题

代码

#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;//若正确选项数量不同,置0if(b == 0) q[j].wr++;//得分为0错误计数加1else 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 << ' ';}
}