1073 多选题常见计分法
思路
提取标准答案串和学生答案字符串:
- 用一个长度为105的string数组存储所有的标准答案字符串;
- 用一个长度为1005的string数组来存储所有的学生答案字符串;
- 每当学生答案字符串读取到 ‘)’ 时,就说明一道题的答案读取完毕了,开始计算该题的选项错误次数以及得分情况(分析原理见下面的详解)
首先明确错误次数是如何计算的,根据题目的案例1可以得知:
- 当多选题的标准答案里有这个选项而答题人没选时,该选项错误次数加1;
- 当多选题的标准答案里没有这个选项而答题人选了,该选项错误次数也加1;
创建一个[105][5]大小的int数组error,来存储每道题每个选项的错误次数。判断答题人答案的时候,在循环选项时就可以简单地区分为四种情况:
- 答案有-答题人没有:选项错误次数+1。漏选
- 答案无-答题人有:选项错误次数+1。错选
- 答案有-答题人也有:选项正确。
- 答案无-答题人也无:无事发生。
用一个flag来记录该题的情况,选项正确flag就加1,漏选不改变flag,错选的话flag就等于-99。计算学生分数时:
- 假如flag正好等于答案字符串的长度,那么拿全部分数。
- 假如flag大于0但是小于答案字符串的长度,那么拿一半的分数。
- 假如flag小于0,则不拿分。
输出环节:
- 依次输出学生的分数
- 循环一遍error数组,找出错误次数的最大值。
- 若最大值不为0,就再循环一遍error数组,把错误次数为最大值的选项全部输出(这时候按照顺序输出正好符合题目的要求)
- 假如错误次数最大值为0,那么就输出too simple
#include<stdio.h>
#include<iostream>
#include<string>
using namespace std;
int score[105]; // 存储每道题的分值
string question[105]; // 存储标准答案字符串
string student[1005]; // 存储学生字符串
double student_score[1005];
int error[105][5]; // 存储每道题每个选项错误次数
int main(void) {
int n, m; cin >> n >> m; // n:学生人数, m:题目数量
for (int i = 0; i < m; i++) {
cin >> score[i];
int r, t; cin >> r >> t; // r:选项个数, t:正确选项个数
for (int j = 0; j < t; j++) {
string x; cin >> x; // 读取每个正确选项
question[i] += x; // 构成标准答案字符串
}
}
getchar(); // 前面用的是cin,会在上面留下一个换行符,需要读取掉
for (int i = 0; i < n; i++) {
string s; // 存储整行的答案
getline(cin, s);
string temp; // 存储每道题的答案
int index = 0; // 记录题号
for (int j = 0; j < s.size(); j++) {
if (s[j] >= 'a' && s[j] <= 'z') { temp += s[j]; }
int flag = 0; // 记录这道题答题情况
if (s[j] == ')') { // 说明一道题结束
for (int k = 0; k < 5; k++) { // 根据标准答案和学生答案中能否找到abcde这些选项来判断
if (question[index].find('a' + k) == -1 && temp.find('a' + k) == -1) { continue; }
if (question[index].find('a' + k) != -1 && temp.find('a' + k) != -1) { flag++; }
if (question[index].find('a' + k) != -1 && temp.find('a' + k) == -1) { error[index][k]++; }
if (question[index].find('a' + k) == -1 && temp.find('a' + k) != -1) { error[index][k]++; flag = -99; }
}
if (flag > 0 && flag != question[index].size()) { // 有漏选
student_score[i] += score[index] / 2.0;
}
if (flag > 0 && flag == question[index].size()) { // 全对
student_score[i] += score[index];
}
index++;
temp.clear();
}
}
}
// 输出学生的分数
for (int i = 0; i < n; i++) {
printf("%.1f\n", student_score[i]);
}
int errorMax = 0; // 存储最大错误次数
for (int i = 0; i < m; i++) {
for (int j = 0; j < 5; j++) {
if (error[i][j] > errorMax) { errorMax = error[i][j]; }
}
}
if (errorMax > 0) {
for (int i = 0; i < m; i++) {
for (int j = 0; j < 5; j++) {
if (error[i][j] == errorMax) {
printf("%d %d-%c\n", errorMax, i + 1, 'a' + j);
}
}
}
}
else {
cout << "Too simple";
}
return 0;
}