1073 多选题常见计分法python3(无超时)

主要记录解决超时的过程,题目不再单列。

一、解题思路

1、首先记录正确答案;
2、针对学生的答题,每次读入一行数据就处理一行;
3、错题使用字典记录,格式:题目编号-选项号:错误次数。

1、最初的代码
#!/usr/bin/env python
# -*-coding:utf-8 -*-
'''
@File    :   1073.py
@Time    :   2020/05/21 12:05:03
@Author  :   Schiller Xu 
@Version :   1.0
@License :   (C)Copyright 2020-2021, SchillerXu
@Desc    :   None
'''

n,m=map(int,input().split())
# test=[input().split() for i in range(m)]
#所有数据
answers=[]
#只有abc等选项
ans=[]
#错误选项
err_ch=dict()

for i in range(m):
    data=input().split()
    answers.append(data)
    answer=set(data[3:])
    ans.append(answer)
    for j in range(int(data[1])):
        c=chr(97+j)
        k=str(i+1)+'-'+c
        if c not in answer:
            err_ch[k]=0

for i in range(n):
    data=input().strip('()')
    data=data.split(') (')
    #print(data)
    score=0
    for j in range(m):
    	#这一题的分数
        s=0
        #这一题错误的选项数
        err=0
        #这一题正确的选项数
        cor=0
        reply=data[j].split()
        for l in range(1,len(reply)):
            if reply[l] not in ans[j]:
                k=str(j+1)+'-'+reply[l]
                err_ch[k]+=1
                err+=1
            else:
                cor+=1
        if err!=0:
            s=0
        elif cor==int(answers[j][2]):
            s=float(answers[j][0])
        else:
            s=float(answers[j][0])*0.5
        score+=s          
    print('{:.1f}'.format(score))

max_err=max(err_ch.values())
if max_err==0:
    print('Too simple')
else:
    for k,v in err_ch.items():
        if v==max_err:
            print(v,k)

这是第一次编码,因为漏掉了“正确选项没被选上也算错误”,没通过。

2、第一次改进(一个超时)

这次改进主要在3个方面:

  1. 增加“没被选上的正确选项”;
  2. 正确答案只记录满分和正确选项(abc);
  3. 处理学生回答时,细化流程,答题正确只需要比对回答和答案是否一致即可,不再统计正确选项和错误选项个数;
#!/usr/bin/env python
# -*-coding:utf-8 -*-
'''
@File    :   1073.py
@Time    :   2020/05/21 12:05:03
@Author  :   Schiller Xu 
@Version :   1.0
@License :   (C)Copyright 2020-2021, SchillerXu
@Desc    :   None
'''

n,m=map(int,input().split())
# test=[input().split() for i in range(m)]
#题目分数
answers=[]
#只有abc等选项
ans=[]
#错误选项
err_ch=dict()

for i in range(m):
    data=input().split()
    answers.append(data[0])
    answer=set(data[3:])
    ans.append(answer)
    for j in range(int(data[1])):
        c=chr(97+j)
        k=str(i+1)+'-'+c
        #所有选项错误个数都初始化为0
        err_ch[k]=0

for i in range(n):
    data=input().strip('()')
    data=data.split(') (')
    #print(data)
    score=0
    for j in range(m):
        #s=0
        err=0
        reply=data[j].split()
        rep=set(reply[1:])
        if rep==ans[j]:
            score+=float(answers[j])
        else:
            #正确选项没被选上也算错误 
            for a in ans[j]:
                if a not in rep:
                    k=str(j+1)+'-'+a
                    err_ch[k]+=1
            for r in rep:
                if r not in ans[j]:
                    k=str(j+1)+'-'+r
                    err_ch[k]+=1
                    err+=1
            if err==0:
                score+=float(answers[j])*0.5
        #score+=s          
    print('{:.1f}'.format(score))

max_err=max(err_ch.values())
if max_err==0:
    print('Too simple')
else:
    for k,v in err_ch.items():
        if v==max_err:
            print(v,k)

这次的代码还有一个可以改进的地方,err_ch在初始化的时候,所有题目的全部选项都加进去了,数据处理完后会存在大量“题目编号-选项号:0”的数据,遍历会浪费很多时间。

3、第二次改进(无超时)
#!/usr/bin/env python
# -*-coding:utf-8 -*-
'''
@File    :   1073.py
@Time    :   2020/05/21 12:05:03
@Author  :   Schiller Xu 
@Version :   1.0
@License :   (C)Copyright 2020-2021, SchillerXu
@Desc    :   None
'''

n,m=map(int,input().split())
# test=[input().split() for i in range(m)]
#题目分数
answers=[]
#只有abc等选项
ans=[]
#错误选项
err_ch=dict()

for i in range(m):
    data=input().split()
    answers.append(data[0])
    answer=set(data[3:])
    ans.append(answer)
    # for j in range(int(data[1])):
    #     c=chr(97+j)
    #     k=str(i+1)+'-'+c
    #     err_ch[k]=0

for i in range(n):
    data=input().strip('()')
    data=data.split(') (')
    #print(data)
    score=0
    for j in range(m):
        #s=0
        err=0
        reply=data[j].split()
        rep=set(reply[1:])
        if rep==ans[j]:
            score+=float(answers[j])
        else:         
            for r in rep:
                if r not in ans[j]:
                    k=str(j+1)+'-'+r
                    try:
                        err_ch[k]+=1
                    except:
                        err_ch[k]=1
                    err+=1
            #正确选项没被选上也算错误 
            for a in ans[j]:
                if a not in rep:
                    k=str(j+1)+'-'+a
                    try:
                        err_ch[k]+=1
                    except:
                        err_ch[k]=1
            if err==0:
                score+=float(answers[j])*0.5
                
        #score+=s          
    print('{:.1f}'.format(score))


lens=len(err_ch)
if lens==0:
    print('Too simple')
else:
    max_err=max(err_ch.values())
    result=[]
    for k,v in err_ch.items():
        if v==max_err:
            r=[v,k,int(k[:-2]),k[-1]]
            result.append(r)
    result.sort(key=lambda x: (x[2],x[3]))
    for r in result:
        print(r[0],r[1])
4、总结

python代码因为是动态编译,所以刷算法的时候比较“吃亏”,容易超时,需要细化流程和数据结构。

PAT乙级其它的一些代码我有空会整理在这篇博客里面:
python3实现PAT乙级算法题库

二、参考资料

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值