「PAT乙级真题解析」Basic Level 1058 选择题 (问题分析+完整步骤+伪代码描述+提交通过代码)

题设要求对比给定的题目信息(分值, 正确选项)和学生的作答, 计算学生分数以及统计出错次数最多的题目. 这意味着如何读取和存储输入(题目信息, 学生作答)以及对比统计是核心内容.

#算法#数据结构#需求分析#c语言#pat考试

Table of Contents

乙级的题目训练主要用来熟悉编程语言的语法和形成良好的编码习惯和编码规范。从小白开始逐步掌握用编程解决问题。

PAT乙级BasicLevelPractice 1058

问题分析

题设要求对比给定的题目信息(分值, 正确选项)和学生的作答, 计算学生分数以及统计出错次数最多的题目. 这意味着如何读取和存储输入(题目信息, 学生作答)以及对比统计是核心内容.

完整描述步骤

  1. 获取输入: 学生人数, 题目数量
  2. 获取输入: 题目信息
  3. 获取输入: 学生作答
  4. 初始化计数器:
    • 学生总得分
    • 各道题目出错次数
    • 单道题目最多出错次数
  5. 对于学生的作答进行检查:
    • 对于每一个题:
      • 检查学生答案个数是否与正确答案个数一致, 如果不一致, 则回答错误
      • 如果个数一致, 检查具体选项是否一致, 如果不一致, 则回答错误
      • 如果回答正确, 则为学生加上题目对应分值
      • 如果回答错误, 该题错误人数+1
      • 如果该题错误人数大于单道题最多出错次数, 则更新单道题最多出错次数
  6. 输出单道题最多出错次数
  7. 检查每一道题的出错次数:
    • 如果题目出错次数等于单道题最多出错次数, 则输出该题编号(编号从1开始)

伪代码描述

  1. get input: student_amount, question_amount, questions

  2. init counter:

    • scores
    • question_wrong_people_amount
    • max_wrong_amount
  3. for each student:

    • for each question, get student's answers and check:
      • init answer_correct = True;
      • if answer_amount != current_question.answer_amount:
        • answer_correct = False;
      • else:
        • for index in range(answer_amount):
          • if answers[index] != current_question.answers[index]:
            • answer_correct = False;
            • break;
      • if answer_correct:
        • scores[student] += current_question.score;
      • else:
        • question_wrong_people_amount[current_question] ++;
      • if question_wrong_people_amount[current_question] > max_wrong_amount:
        • max_wrong_amount = question_wrong_people_amount[current_question];
  4. print(max_wrong_amount)

  5. for question_index, amount in question_wrong_people_amount:

    • if amount == max_wrong_amount:
      • print(question_index)

完整提交代码

/*
# 问题分析
题设要求对比给定的题目信息(分值, 正确选项)和学生的作答, 计算学生分数以及统计出错次数最多的题目.
这意味着如何读取和存储输入(题目信息, 学生作答)以及对比统计是核心内容.
 
 
# 完整描述步骤
1. 获取输入: 学生人数, 题目数量
2. 获取输入: 题目信息
3. 获取输入: 学生作答
4. 初始化计数器:
    - 学生总得分
    - 各道题目出错次数
    - 单道题目最多出错次数
5. 对于学生的作答进行检查:
    - 对于每一个题:
        - 检查学生答案个数是否与正确答案个数一致, 如果不一致, 则回答错误
        - 如果个数一致, 检查具体选项是否一致, 如果不一致, 则回答错误
        - 如果回答正确, 则为学生加上题目对应分值
        - 如果回答错误, 该题错误人数+1
        - 如果该题错误人数大于单道题最多出错次数, 则更新单道题最多出错次数
6. 输出单道题最多出错次数
7. 检查每一道题的出错次数:
    - 如果题目出错次数等于单道题最多出错次数, 则输出该题编号(编号从1开始)
 
# 伪代码描述
1. get input: student_amount, question_amount, questions
2. init counter:
    - scores
    - question_wrong_people_amount
    - max_wrong_amount
 
3. for each student:
    - for each question, get student's answers and check:
        - init answer_correct = True;
        - if answer_amount != current_question.answer_amount:
            - answer_correct = False;
        - else:
            - for index in range(answer_amount):
                - if answers[index] != current_question.answers[index]:
                    - answer_correct = False;
                    - break;
        - if answer_correct:
            - scores[student] += current_question.score;
        - else:
            - question_wrong_people_amount[current_question] ++;
        - if question_wrong_people_amount[current_question] > max_wrong_amount:
            - max_wrong_amount = question_wrong_people_amount[current_question];
6. print(max_wrong_amount)
7. for question_index, amount in question_wrong_people_amount:
    - if amount == max_wrong_amount:
        - print(question_index)
*/
 
#include <stdio.h>
#define ANSWER_WRONG 0
#define ANSWER_RIGHT 1
 
typedef struct {
  int score;
  int option_amount;
  int answer_amount;
  char answers[6];
} question;
 
question questions[100];
 
int check_answer(int answer_amount, char* answers, int question_index) {
  if (answer_amount != questions[question_index].answer_amount) {
    return ANSWER_WRONG;
  }
 
  for (int k = 0; k < answer_amount; k++) {
    if (answers[k] != questions[question_index].answers[k]) {
      return ANSWER_WRONG;
    }
  }
 
  return ANSWER_RIGHT;
}
 
void read_questions(int question_amount) {
  for (int i = 0; i < question_amount; i++) {
    scanf("%d %d %d", &questions[i].score, &questions[i].option_amount,
          &questions[i].answer_amount);
    for (int j = 0; j < questions[i].answer_amount; j++) {
      scanf(" %c", &questions[i].answers[j]);
    }
  }
}
 
int main() {
  int student_amount, question_amount;
  scanf("%d %d", &student_amount, &question_amount);
 
  read_questions(question_amount);
 
  int scores[student_amount];
  memset(scores, 0, sizeof(int) * student_amount);
 
  int question_wrong_people_amount[question_amount];
  memset(question_wrong_people_amount, 0, sizeof(int) * question_amount);
 
  getchar();
  int max_wrong_amount = 0;
  int answer_amount;
  char answers[6];
  for (int i = 0; i < student_amount; i++) {
    for (int j = 0; j < question_amount; j++) {
      scanf("(%d", &answer_amount);
      for (int k = 0; k < answer_amount; k++) {
        scanf(" %c", &answers[k]);
      }
 
      int check_result = check_answer(answer_amount, answers, j);
      if (check_result == ANSWER_RIGHT) {
        scores[i] += questions[j].score;
      } else {
        question_wrong_people_amount[j]++;
        if (question_wrong_people_amount[j] > max_wrong_amount) {
          max_wrong_amount = question_wrong_people_amount[j];
        }
      }
      scanf(")");
      getchar();
    }
  }
 
  for (int i = 0; i < student_amount; i++) {
    printf("%d\n", scores[i]);
  }
 
  if (max_wrong_amount == 0) {
    printf("Too simple");
  } else {
    printf("%d", max_wrong_amount);
    for (int i = 0; i < question_amount; i++) {
      if (question_wrong_people_amount[i] == max_wrong_amount) {
        printf(" %d", i + 1);
      }
    }
  }
 
  printf("\n");
  return 0;
}
「PAT乙级真题解析」Basic Level 1058 选择题 (问题分析+完整步骤+伪代码描述+提交通过代码) | 生活糖果