PAT 乙级 1073 多选题常见计分法

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

将做题情况与错题情况写入两个数组中,最后统计在两个数组之中进行,根据对应的映射来进行。值得注意的是:1.第39行进行判断的程序,一开始用一个单纯的else结果仅得两分,想了几个小时也没有结果,后决定将else if补完,使条件达到正确,结果便通过了 。2.少选的选项一开始没有考虑进错题中,觉得太麻烦,其实将其反映至对应的表中即可,无论是少选还是错选都要算错题 3.少选的分数如何计算,需要将少选的题全部选出,这里控制flag可以实现  4.关于多个最大值问题,存放到二维数组中,然后遍历数组即可(若数组量小可以这么做,本题在做的时候复杂化了,量大或者无法决定时可以考虑下二维指针)4.关于set和map,vector这三个容器还没有掌握,可能用于大容量数据的查重会有用。剩下还是先按照基本的一维二维数组来做。5.突然想到二维指针怎么用,在乙级1050中,二维指针的出现是用于无法确定大小的矩阵中,定义成m与n,因为在这题中矩阵的维数由计算得。

代码如下:

#include <bits/stdc++.h>

using namespace std;

struct grade
{
    double full;
    int na;
    int nr;//正确选项个数
    int zhengque[5]= {0}; //记录下每一题的正确选项
} gg[110];

int b[110][5];//记录下做题的情况

int d[110][5];//记录下错题的情况,需要用一个Int型矩阵表示

int max=0;//max用于记录最大错题的数目

double judge(int j)
{
    double fenshu=0;
    int flag=0;//进行判断
    int count0=0;//代表在1题中做对的选项
    for(int i=0; i<5; i++)
    {
        if(gg[j].zhengque[i]!=b[j][i])
        {
            if(gg[j].zhengque[i]==1&&b[j][i]==0)
            {
                d[j][i]++;
            }
            else if(gg[j].zhengque[i]==0&&b[j][i]==1)
            {
                flag=1;
                d[j][i]++;
                //相当于出现了错选
            }
        }
        else if(gg[j].zhengque[i]==1&&b[j][i]==1)
        {
            count0++;
        }
    }
    if(flag==1)
    {
        fenshu=0;
    }
    else if(flag==0)
    {
        if(count0<gg[j].nr)
        {
            fenshu=0.5*gg[j].full;
        }
        else if(count0==gg[j].nr)
        {
            fenshu=gg[j].full;
        }
    }
    return fenshu;
}//这个函数是对不同学生的每一道题进行判断,需要的最大值是错误最多的题目的选项,先记录下错误的情况

int main()
{
    int N,M;
    cin>>N>>M;//输入学生人数与题目的数目,学生人数为N,题目数目为M
    char c;//输入字符,主要是应对选项的输入
    for(int i=0; i<M; i++)
    {
        cin>>gg[i].full>>gg[i].na>>gg[i].nr;
        for(int j=0; j<gg[i].nr; j++)
        {
            cin>>c;
            gg[i].zhengque[(int)c-(int)'a']=1;
        }
    }//可以每做一步便对结果进行输出的检验,思路一定要清晰
    int k=0;//控制每一个选项
    for(int i=0;i<M;i++)
    {
        for(int j=0;j<5;j++)
        {
            b[i][j]=0;
            d[i][j]=0;
        }
    }
    for(int i=0; i<N; i++)
    {
        double sum=0;
        for(int ii=0;ii<M;ii++)
        {
            for(int jj=0;jj<5;jj++)
            {
                b[ii][jj]=0;
            }
        }
        for(int j=0; j<M; j++)
        {
            cin>>c;//左括号
            cin>>k;
            for(int l=0; l<k; l++)
            {
                cin>>c;//输入每个学生的选项
                b[j][(int)c-(int)'a']=1;
            }
            cin>>c;//为右括号
            //下面开始进行分数与错题的统计
            sum+=judge(j);
        }
        cout<<setiosflags(ios::fixed)<<setprecision(1)<<sum<<endl;
    }//输入每个学生的答题情况,输出其分数
    //在输出分数完成后需要进行错误题数的统计,也是最难的
    int max=d[0][0];
    int count=0;
    for(int i=0; i<M; i++)
    {
        for(int j=0; j<5; j++)
        {
            if(d[i][j]!=0)
            {
                count++;
            }
            if(d[i][j]>max)
            {
                max=d[i][j];
            }
        }
    }
    if(count!=0)
    {
        for(int i=0; i<M; i++)
        {
            for(int j=0; j<5; j++)
            {
                if(d[i][j]==max)
                {
                    cout<<d[i][j]<<" "<<i+1<<"-"<<char('a'+j)<<endl;
                }
            }
        }
    }
    else if(count==0)
    {
        cout<<"Too simple"<<endl;
    }
    return 0;
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值