批改多选题是比较麻烦的事情,有很多不同的计分方法。有一种最常见的计分方法是:如果考生选择了部分正确选项,并且没有选择任何错误选项,则得到 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
解题思路:
将近200行的一大坨,但是一次就过了
c++代码如下:
#include <bits/stdc++.h>
using namespace std;
//将错误答案的类
bool toosimple = true;
struct ss
{
ss(int num,char data,int times)
:_num(num)
,_data(data)
,_times(times)
{
}
//将错误答案进行排序
bool operator<(const ss &e) const
{
if(this->_times != e._times) return this->_times > e._times;
else if(this->_num != e._num) return this->_num < e._num;
else return this->_data < e._data;
}
int _num;
char _data;
int _times;
};
multiset<ss> s;//存储错误的答案的次数和具体题目
int find_s(string a,string b,int num)
{
for(int i = 0;i < b.size();++i)
{
if(a.find(b[i]) == string :: npos)
{
auto t = ::s.begin();
while(t != ::s.end())
{
if(t->_data == b[i] && t->_num == num) break;
++t;
}
if(t == ::s.end())
{
ss new_ss(num,b[i],1);
::s.insert(new_ss);
}
else
{
ss new_ss(num,b[i],t->_times+1);
::s.erase(t);
::s.insert(new_ss);
}
}
}
//判断两遍,寻找不同
string t = a;
a = b;
b = t;
for(int i = 0;i < b.size();++i)
{
if(a.find(b[i]) == string :: npos)
{
auto t = ::s.begin();
while(t != ::s.end())
{
if(t->_data == b[i] && t->_num == num) break;
++t;
}
if(t == ::s.end())
{
ss new_ss(num,b[i],1);
::s.insert(new_ss);
}
else
{
ss new_ss(num,b[i],t->_times+1);
::s.erase(t);
::s.insert(new_ss);
}
}
}
return -1;
}
int func(string a,string b,int num)
{
sort(a.begin(),a.end());
sort(b.begin(),b.end());
if(b.size() > a.size()) return find_s(a,b,num);
for(int i = 0;i < b.size();++i)
{
if(a.find(b[i]) == string :: npos)
{
return find_s(a,b,num);
}
}
if(b!=a)
{
find_s(a,b,num);
return 0;
}
else
{
return 1;
}
}
int main()
{
int sum = 0;
int x,y;
cin >> x >> y;
vector<string> answer;
float student[x];
float add[y];
memset(student,0,x*4);
memset(add,0,y*4);
// 录入答案
for(int i = 0;i < y;++i)
{
cin >> add[i];
sum += add[i];
int n;
cin >> n >> n;
string s = "";
while(n--)
{
char c;
cin >> c;
s += c;
}
answer.push_back(s);
}
//判断是否作对,并且加分
for(int i = 0;i < x;++i)
{
for(int j = 0;j < y;++j)
{
char c;
cin >> c;
string stu = "";
int num;
cin >> num;
while(num--)
{
cin >> c;
stu += c;
}
int res = func(answer[j],stu,j+1);
if(res == 0)
{
student[i] += add[j]*1.0/2;
}
else if(res == 1)
{
student[i] += add[j]*1.0;
}
cin >> c;
}
}
//输出
for(auto &elem : student)
{
if(elem != sum) toosimple = false;
printf("%.1f\n",elem);
}
if(toosimple)
{
cout << "Too simple";
}
else
{
auto out = s.begin();
int max = out->_times;
while(out->_times == max)
{
cout << max << " " << out->_num << "-" << out->_data << endl;
++out;
}
}
return 0;
}
标签:选项,string,计分,int,多选题,times,ss,num,No.0087
From: https://blog.csdn.net/2301_76783671/article/details/139810956