PAT 1073 多选题常见计分法

1073 多选题常见计分法(20 分)
批改多选题是比较麻烦的事情,有很多不同的计分方法。有一种最常见的计分方法是:如果考生选择了部分正确选项,并且没有选择任何错误选项,则得到 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




解析

这题有些复杂,搞得我有些晕。发生了段错误(;´д`)ゞ


这题的核心就是在判断学生的分数,我是怎么判断的:
对每一个题目:我都会保存每一个选项错了多少次。即

vector<int> Case;
Case[0]代表A,Case[1]代表B,Case[2]代表C,Case[3]代表D,Case[4]代表E。

然后每处理一个学生的一道题的选择情况:
对每一个选项:无非是下面4种 :
①正确选项无,学生选项无
②正确选项无,学生选项有
③正确选项有,学生选项无
④正确选项有,学生选项有
这里写图片描述
如果是第②种情况:代表学生这题选错了,0分
如果是第③④种情况:代表学生这个选项是没选或对了。都属于可能得到的情况。我用一个int值保存学生这题选对的选项。如果和这题正确选项的数量一样。得满分,否则一半分数。
如果是第①中情况,不用管。
我这种判断方法很垃圾。这篇博主的判断方法很不错:柳婼


最后就是收尾工作了。判断错题最多的选项。在之前判断中我已经把每题的错误情况登记了。这里只用找最大值就OK了。
Code:

#include<bits/stdc++.h>
using namespace std;
struct problem{
    int rating;
    int choose;
    vector<char> correct;
    vector<int> Case;
};
int main()
{
    int N,M;
    cin>>N>>M;
    vector<problem> data(M);
    for(int i=0;i<M;i++){
        int temp;
        char temp1;
        cin>>data[i].rating>>temp>>data[i].choose;
        for(int j=0;j<data[i].choose;j++){
            cin>>temp1;
            data[i].correct.push_back(temp1);
        }
        data[i].Case={0,0,0,0,0};
    }
    getchar();
    for(int i=0;i<N;i++){
        double score=0.0;
        string student;
        getline(cin,student);
        auto begin = student.cbegin();
        for(int j=0;j<M;j++){               
            vector<char> cho;
            while(*begin++ !=')'){
                if(isalpha(*begin))
                    cho.push_back(*begin);
            }
            bool flag1=true;
            int co=0;
            for(char ch='a';ch!='f';ch++){
                auto it1 = find(cho.cbegin(),cho.cend(),ch);
                auto it2 = find(data[j].correct.cbegin(),data[j].correct.cend(),ch);
                if(it2 ==data[j].correct.cend()){
                    if(it1 !=cho.cend()){
                        flag1=false;            
                        data[j].Case[ch-'a']++;
                    }
                }
                else{
                    if(it1 != cho.cend())
                        co++;                       
                    else
                        data[j].Case[ch-'a']++;
                }
            }
            if(flag1==true){
                if(co==data[j].choose)
                    score+=data[j].rating;
                else
                    score+=(double)data[j].rating/2;            
            }
        }
        printf("%.1f\n",score);
    }
    int max=0;
    vector<pair<int,int>> _max;
    for(int i=0;i<M;i++){
        for(int j=0;j<5;j++){
            if(data[i].Case[j]>max){
                max=data[i].Case[j];
                _max.clear();
                _max.push_back(make_pair(i,j));
            }               
            else if(data[i].Case[j]==max)
                _max.push_back(make_pair(i,j));
        }
    }
    if(max==0)
        cout<<"Too simple";
    else{
        for(auto x:_max){
            cout<<max<<" "<<x.first+1<<"-"<<(char)(x.second+'a')<<endl;
        }       
    }   
}

猜你喜欢

转载自blog.csdn.net/weixin_41256413/article/details/82223477