1073 多选题常见计分法 (20 分)

原题链接
这道题,emmmmmm,贼坑了

测试点4应该是数组大小的问题

这里使用了标记法,108个码标记,提高程序运行的速度

#include<iostream>
#include<string>
#include<cstdlib>
#include<cstring>
#include<cstdio>
using namespace std;

struct node
{
    double score;
    int anscnt;
    int accnt;
    int a[109]={0};//标记字母是否在答案里面
    char ans[1000];//保存字母答案

};
int main()
{
    double socre[1100]={0};//保存成绩
    node ans[1100];//保存争取答案
    int a[1100][109];//保存错误的信息和次数
    int n,m;
    cin>>n>>m;
    for(int i=0;i<m;i++)
    {
        cin>>ans[i].score;
        cin>>ans[i].anscnt;
        cin>>ans[i].accnt;
        for(int j=0;j<ans[i].accnt;j++)
        {
            cin>>ans[i].ans[j];
            ans[i].a[ans[i].ans[j]]=1;//标记
        }
    }
    for(int i=0;i<n;i++)
    {
        char temp;
        double socore=0;
        for(int k=0;k<m;k++)
        {
            cin>>temp;
            int flag[109];
            int flag1=0;
            int index=0;
            memset(flag,0,sizeof(flag));//一定要清空这个lag数组
            int z;
            cin>>z;
            for(int j=0;j<z;j++)
            {
                cin>>temp;
                if(ans[k].a[temp]==0)//如果当前的标记没有出现过,说明是不合法的答案
                {
                    a[k][temp]++;
                    flag1=1;//标记有不合法的的答案就已经是0分了
                }
                flag[temp]=1;//标记当前结点已经访问过来
            }
            if(flag1==0)//如果没有出现错误答案
            {
                if(z==ans[k].accnt)//如果和正确答案的个个数就相同就是满分
                    socore+=ans[k].score;
                else//如果不相同就是一半的分数
                    socore+=ans[k].score*1.0/2;
            }
            for(int k1=0;k1<ans[k].accnt;k1++)//出现错误答案后,说明题目正确答案也没有出现过就是也是错误答案,所以直接也加进去
            {
                int index=ans[k].ans[k1];
                if(flag[index]==0)
                {
                    a[k][index]++;
                }
            }
            getchar();
            getchar();
        }
        socre[i]+=socore;
    }
    for(int i=0;i<n;i++)
    {
        printf("%0.1lf\n",socre[i]);
    }
    int max=-9999;
    for(int i=0;i<m;i++)//找到出现次数最多的答案
    {
        for(int j=0;j<=108;j++)
        {
            if(a[i][j]>=max)
                max=a[i][j];
        }
    }
    if(max==0)
    {
        cout<<"Too simple"<<endl;
        return 0;
    }
    for(int i=0;i<m;i++)
    {
        for(int j=0;j<=108;j++)
        {
            if(a[i][j]==max)
                cout<<max<<" "<<i+1<<"-"<<char(j)<<endl;
        }
    }
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值