PAT乙级真题1073 || 多选题常见计分法(详解,C/C++示例,测试点分析)
【欢迎关注微信公众号:计算机黑科学大全,对话框回复:PAT乙级真题】获取全部真题详解及代码示例
个人博客地址:https://mzwang.top
多选题常见计分法
题目描述:
批改多选题是比较麻烦的事情,有很多不同的计分方法。有一种最常见的计分方法是:如果考生选择了部分正确选项,并且没有选择任何错误选项,则得到 50% 分数;如果考生选择了任何一个错误的选项,则不能得分。本题就请你写个程序帮助老师批改多选题,并且指出哪道题的哪个选项错的人最多。
输入格式:
输入在第一行给出两个正整数 N(≤1000)和 M(≤100),分别是学生人数和多选题的个数。随后 M 行,每行顺次给出一道题的满分值(不超过 5 的正整数)、选项个数(不少于 2 且不超过 5 的正整数)、正确选项个数(不超过选项个数的正整数)、所有正确选项。注意每题的选项从小写英文字母 a 开始顺次排列。各项间以 1 个空格分隔。最后 N 行,每行给出一个学生的答题情况,其每题答案格式为
(选中的选项个数 选项1 ……)
,按题目顺序给出。注意:题目保证学生的答题情况是合法的,即不存在选中的选项数超过实际选项数的情况。输出格式:
按照输入的顺序给出每个学生的得分,每个分数占一行,输出小数点后 1 位。最后输出错得最多的题目选项的信息,格式为:
错误次数 题目编号(题目按照输入的顺序从1开始编号)-选项号
。如果有并列,则每行一个选项,按题目编号递增顺序输出;再并列则按选项号递增顺序输出。行首尾不得有多余空格。如果所有题目都没有人错,则在最后一行输出Too simple
。输入样例1:
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) (3 b d e) (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) (1 c) (4 a b c d)
输出样例1:
3.5 6.0 2.5 2 2-e 2 3-a 2 3-b
输入样例2:
2 2 3 4 2 a c 2 5 1 b (2 a c) (1 b) (2 a c) (1 b)
输出样例2:
5.0 5.0 Too simple
题目来源:PAT乙级1073
作者:CHEN, Yue
单位:浙江大学
问题解决:
解题思想
此题与patb1058类似。某道题的某个选项(比如第2题的选项e
)错误分以下两种情况:
- 选择了一个正确答案中没有的选项
- 正确答案中有的选项没有选择
坑点提醒
(测试点3和4错误)最多的错误次数是指某选项错误最多的那个题的选项错误数而不是题目错误数。一开始我理解成了某道题的错误最多的情况,这样会导致测试点3和4错误。
代码示例(C/C++)
#include <iostream>
#include <cstdio>
#include <map>
#include <algorithm>
const int MAXM = 101;
struct question {
int total_score, num_option, cor_num_option;
int cor_option[105] = {0}; //
int err_option[105] = {0};
}quest[MAXM];
using namespace std;
int main() {
int N, M;
scanf("%d%d", &N, &M);
for(int i = 0; i < M; i++) {
scanf("%d%d%d", &quest[i].total_score, &quest[i].num_option, &quest[i].cor_num_option);
for(int j = 0; j < quest[i].cor_num_option; j++) { //注意此处
char tmp;
cin >> tmp;
quest[i].cor_option[tmp] = 1;
}
}
for(int i = 0; i < N; i++) {
double score_count = 0.0;
for(int j = 0; j < M; j++) {
while(getchar() != '(');
int num, flag = 0;
scanf("%d",&num);
int tmp[105] = {0};
for(int k = 0; k < num; k++) {
char t;
cin >> t;
tmp[t] = 1;
if(quest[j].cor_option[t] == 0) {
flag = 1;
}
}
for(int k = 'a'; k <= 'e'; k++) {
if(quest[j].cor_option[k] != tmp[k]) { //注意此处
quest[j].err_option[k]++;
}
}
if(flag == 0) {
if(num == quest[j].cor_num_option) {
score_count += quest[j].total_score;
}
else {
score_count += (double)quest[j].total_score / 2;
}
}
}
printf("%.1lf\n", score_count);
}
int maxnum = quest[0].err_option['a']; //某选项错误最多的那个题的选项错误数
for(int i = 0; i < M; i++) {
for(int j = 'a'; j <= 'e'; j++) {
if(maxnum < quest[i].err_option[j]) {
maxnum = quest[i].err_option[j];
}
}
}
if(maxnum == 0) { //全部正确
printf("Too simple\n");
}
else {
for(int i = 0; i < M; i++) {
for(int j = 'a'; j <= 'e'; j++) {
if(maxnum == quest[i].err_option[j]) {
printf("%d %d-%c\n", maxnum, i + 1, j);
}
}
}
}
return 0;
}