Python刷题记录(71-80)

Python刷题记录(71-80)

题目来源PTA平台

PAT (Basic Level) Practice (中文)

@TOC


1071 小赌怡情

常言道“小赌怡情”。这是一个很简单的小游戏:首先由计算机给出第一个整数;然后玩家下注赌第二个整数将会比第一个数大还是小;玩家下注 t 个筹码后,计算机给出第二个数。若玩家猜对了,则系统奖励玩家 t 个筹码;否则扣除玩家 t 个筹码。

注意:玩家下注的筹码数不能超过自己帐户上拥有的筹码数。当玩家输光了全部筹码后,游戏就结束。

输入格式:

输入在第一行给出 2 个正整数 T 和 K(≤ 100),分别是系统在初始状态下赠送给玩家的筹码数、以及需要处理的游戏次数。随后 K 行,每行对应一次游戏,顺序给出 4 个数字:

n1 b t n2

其中 n1n2 是计算机先后给出的两个[0, 9]内的整数,保证两个数字不相等。b 为 0 表示玩家赌,为 1 表示玩家赌t 表示玩家下注的筹码数,保证在整型范围内。

输出格式:

对每一次游戏,根据下列情况对应输出(其中 t 是玩家下注量,x 是玩家当前持有的筹码量):

  • 玩家赢,输出 Win t! Total = x.
  • 玩家输,输出 Lose t. Total = x.
  • 玩家下注超过持有的筹码量,输出 Not enough tokens. Total = x.
  • 玩家输光后,输出 Game Over. 并结束程序。

输入样例 1:

100 4
8 0 100 2
3 1 50 1
5 1 200 6
7 0 200 8

输出样例 1:

Win 100!  Total = 200.
Lose 50.  Total = 150.
Not enough tokens.  Total = 150.
Not enough tokens.  Total = 150.

输入样例 2:

100 4
8 0 100 2
3 1 200 1
5 1 200 6
7 0 200 8

输出样例 2:

Win 100!  Total = 200.
Lose 200.  Total = 0.
Game Over.

思路:

输入后按照题目要求进行操作即可

要注意Game Over后结束程序

代码:

t, k = map(int, input().split())
for i in range(k):
    l = [int(x) for x in input().split()]
    if l[2] > t:
        print('Not enough tokens.  Total = %d.' % t)
    else:
        if l[0] < l[3]:
            if l[1] == 1:
                t += l[2]
                print('Win %d!  Total = %d.' % (l[2], t))
            else:
                t -= l[2]
                print('Lose %d.  Total = %d.' % (l[2], t))
        else:
            if l[1] == 1:
                t -= l[2]
                print('Lose %d.  Total = %d.' % (l[2], t))
            else:
                t += l[2]
                print('Win %d!  Total = %d.' % (l[2], t))
        if t <= 0:
            print('Game Over.')
            break

1072 开学寄语

下图是上海某校的新学期开学寄语:天将降大任于斯人也,必先删其微博,卸其 QQ,封其电脑,夺其手机,收其 ipad,断其 wifi,使其百无聊赖,然后,净面、理发、整衣,然后思过、读书、锻炼、明智、开悟、精进。而后必成大器也!

本题要求你写个程序帮助这所学校的老师检查所有学生的物品,以助其成大器。

输入格式:

输入第一行给出两个正整数 N(≤ 1000)和 M(≤ 6),分别是学生人数和需要被查缴的物品种类数。第二行给出 M 个需要被查缴的物品编号,其中编号为 4 位数字。随后 N 行,每行给出一位学生的姓名缩写(由 1-4 个大写英文字母组成)、个人物品数量 K(0 ≤ K ≤ 10)、以及 K 个物品的编号。

输出格式:

顺次检查每个学生携带的物品,如果有需要被查缴的物品存在,则按以下格式输出该生的信息和其需要被查缴的物品的信息(注意行末不得有多余空格):

姓名缩写: 物品编号1 物品编号2 ……

最后一行输出存在问题的学生的总人数和被查缴物品的总数。

输入样例:

4 2
2333 6666
CYLL 3 1234 2345 3456
U 4 9966 6666 8888 6666
GG 2 2333 7777
JJ 3 0012 6666 2333

输出样例:

U: 6666 6666
GG: 2333
JJ: 6666 2333
3 5

思路:

将违禁物品存入列表,再将每个学生的物品进行对比,记录下物品数和人数即可

代码:

N, M = map(int, input().split())
lst = input().split()
pnum, onum = 0, 0
for i in range(N):
    t = input().split()
    ms = []
    for i in t[2:]:
        if i in lst:
            ms.append(i)
            onum += 1
    if len(ms) > 0:
        print('{}: {}'.format(t[0], ' '.join(ms)))
        pnum += 1
print(pnum, onum)

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

思路:

这题有点复杂,借用下Raaay233大佬的思路和代码

使用input()[1:-1].split(’) (’)可以去掉括号,太妙了

先把去掉学生答案和标准答案中的交集去掉,然后如果两者都为空代表全对加满分;如果学生答案为空,标准答案不为空代表部分正确,加一半分;其他情况代表错误

使用字典存储错误情况,使用(题号,选项)的元组作为key值(妙不可言),然后常规思路找最值,输出即可

代码:

n = input().split()
ans = []
for i in range(int(n[1])):
    tmp = input().split()
    tmp[0] = float(tmp[0])
    ans.append(tmp)

l = ['a', 'b', 'c', 'd', 'e']
wrong = {
     }

for i in range(int(n[0])):
    stu = []
    score = 0.0
    m = input()[1:-1].split(') (')  # 分离
    for x in m:
        stu.append(x.split())
    for j in range(int(n[1])):
        stu_l = stu[j][1:]  # 学生答案
        ans_l = ans[j][3:]  # 正确答案
        for a in l:
            if a in stu_l and a in ans_l:  # 移除两者的交集
                stu_l.remove(a)
                ans_l.remove(a)
        if not stu_l and not ans_l:  # 两者为空,全对
            score += ans[j][0]
        elif not stu_l and ans_l:  # 学生答案为空,部分正确
            score += ans[j][0] / 2
        if stu_l:
            for k in stu_l:
                if (j + 1, k) in wrong.keys():  # 元组作为key,标识题号和选项
                    wrong[(j + 1, k)] += 1
                else:
                    wrong[(j + 1, k)] = 1
        if ans_l:
            for k in ans_l:
                if (j + 1, k) in wrong.keys():
                    wrong[(j + 1, k)] += 1
                else:
                    wrong[(j + 1, k)] = 1
    print(score)
if not wrong:
    print("Too simple")
else:
    maxx = max(wrong.values())
    rst = []
    for k, v in wrong.items():
        if v == maxx:
            rst.append(k)
    rst.sort(key=lambda x: x[1])
    rst.sort(key=lambda x: x[0])
    for i in rst:
        print('{} {}-{}'.format(maxx, i[0], i[1]))

1074 宇宙无敌加法器

地球人习惯使用十进制数,并且默认一个数字的每一位都是十进制的。而在 PAT 星人开挂的世界里,每个数字的每一位都是不同进制的,这种神奇的数字称为“PAT数”。每个 PAT 星人都必须熟记各位数字的进制表,例如“……0527”就表示最低位是 7 进制数、第 2 位是 2 进制数、第 3 位是 5 进制数、第 4 位是 10 进制数,等等。每一位的进制 d 或者是 0(表示十进制)、或者是 [2,9] 区间内的整数。理论上这个进制表应该包含无穷多位数字,但从实际应用出发,PAT 星人通常只需要记住前 20 位就够用了,以后各位默认为 10 进制。

在这样的数字系统中,即使是简单的加法运算也变得不简单。例如对应进制表“0527”,该如何计算“6203 + 415”呢?我们得首先计算最低位:3 + 5 = 8;因为最低位是 7 进制的,所以我们得到 1 和 1 个进位。第 2 位是:0 + 1 + 1(进位)= 2;因为此位是 2 进制的,所以我们得到 0 和 1 个进位。第 3 位是:2 + 4 + 1(进位)= 7;因为此位是 5 进制的,所以我们得到 2 和 1 个进位。第 4 位是:6 + 1(进位)= 7;因为此位是 10 进制的,所以我们就得到 7。最后我们得到:6203 + 415 = 7201。

输入格式:

输入首先在第一行给出一个 N 位的进制表(0 < N ≤ 20),以回车结束。 随后两行,每行给出一个不超过 N 位的非负的 PAT 数。

输出格式:

在一行中输出两个 PAT 数之和。

输入样例:

30527
06203
415

输出样例:

7201

思路:

将输入的数据都倒序,把N中的0都改成10

然后模拟手算加法使用f标记是否进位,答案添加进数组,最后倒序转换成int(去最前面的0,同时避免答案0的错误)输出即可

代码:

N = list(map(int, input()))
for i in range(len(N)):
    if N[i] == 0:
        N[i] = 10
a = list(map(int, input()))
b = list(map(int, input()))
N.reverse()
a.reverse()
b.reverse()
la, lb = len(a), len(b)
i, f = 0, 0
ans = []
while(i < la or i < lb):
    if i < la and i < lb:
        t = a[i]+b[i]+f
    elif i < la:
        t = f+a[i]
    else:
        t = f+b[i]
    f, t = divmod(t, N[i])
    ans.append(t)
    i += 1
if f != 0:
    ans.append(f)
ans.reverse()
print(int(''.join(str(x)for x in ans)))

1075 链表元素分类

给定一个单链表,请编写程序将链表元素进行分类排列,使得所有负值元素都排在非负值元素的前面,而 [0, K] 区间内的元素都排在大于 K 的元素前面。但每一类内部元素的顺序是不能改变的。例如:给定链表为 18→7→-4→0→5→-6→10→11→-2,K 为 10,则输出应该为 -4→-6→-2→7→0→5→10→18→11。

输入格式:

每个输入包含一个测试用例。每个测试用例第 1 行给出:第 1 个结点的地址;结点总个数,即正整数N (≤105);以及正整数K (≤103)。结点的地址是 5 位非负整数,NULL 地址用 −1 表示。

接下来有 N 行,每行格式为:

Address Data Next

其中 Address 是结点地址;Data 是该结点保存的数据,为 [−105,105] 区间内的整数;Next 是下一结点的地址。题目保证给出的链表不为空。

输出格式:

对每个测试用例,按链表从头到尾的顺序输出重排后的结果链表,其上每个结点占一行,格式与输入相同。

输入样例:

00100 9 10
23333 10 27777
00000 0 99999
00100 18 12309
68237 -6 23333
33218 -4 00000
48652 -2 -1
99999 5 68237
27777 11 48652
12309 7 33218

输出样例:

33218 -4 68237
68237 -6 48652
48652 -2 12309
12309 7 00000
00000 0 99999
99999 5 23333
23333 10 00100
00100 18 27777
27777 11 -1

思路:

用两个列表存储每个节点的data和next,随后将其串成链表存入列表

遍历链表根据data分成三类然后输出即可

但是测试点5还是超时了,这里已经使用了sys库中入读取和写入函数并且实现分配列表空间来减少使用append函数的时间,最后也避免的了合并链表来减少时间,没办法了,以后再看吧

这里需要注意的是数据中可能会存在无用节点,此外如果不和并列表需要考虑只有小于0的值,只有0-k的值,只有小于0和大于k的值的情况

代码:

import sys

strat, N, K = map(int, sys.stdin.readline().split())
data = [0 for i in range(100005)]
next = [0 for j in range(100005)]
lst = [[] for j in range(100005)]
num = 0
for i in range(N):
    a, b, c, = map(int, sys.stdin.readline().split())
    data[a] = b
    next[a] = c
while strat != -1:
    lst[num] = [strat, data[strat], next[strat]]
    num += 1
    strat = next[strat]
a = [[] for j in range(num)]
b = [[] for j in range(num)]
c = [[] for j in range(num)]
la, lb, lc = 0, 0, 0
for i in range(num):
    if lst[i][1] < 0:
        a[la] = lst[i]
        la += 1
    elif 0 <= lst[i][1] <= K:
        b[lb] = lst[i]
        lb += 1
    else:
        c[lc] = lst[i]
        lc += 1
if la > 0:
    for i in range(la-1):
        sys.stdout.write('%05d %d %05d\n' % (a[i][0], a[i][1], a[i+1][0]))
    if lb > 0:
        sys.stdout.write('%05d %d %05d\n' % (a[la-1][0], a[la-1][1], b[0][0]))
    elif lc > 0:
        sys.stdout.write('%05d %d %05d\n' % (a[la-1][0], a[la-1][1], c[0][0]))
    else:
        sys.stdout.write('%05d %d -1\n' % (a[la-1][0], a[la-1][1]))
if lb > 0:
    for i in range(lb-1):
        sys.stdout.write('%05d %d %05d\n' % (b[i][0], b[i][1], b[i+1][0]))
    if lc > 0:
        sys.stdout.write('%05d %d %05d\n' % (b[lb-1][0], b[lb-1][1], c[0][0]))
    else:
        sys.stdout.write('%05d %d -1\n' % (b[lb-1][0], b[lb-1][1]))
if lc > 0:
    for i in range(lc-1):
        sys.stdout.write('%05d %d %05d\n' % (c[i][0], c[i][1], c[i+1][0]))
    sys.stdout.write('%05d %d -1\n' % (c[lc-1][0], c[lc-1][1]))

1076 Wifi密码

下面是微博上流传的一张照片:“各位亲爱的同学们,鉴于大家有时需要使用 wifi,又怕耽误亲们的学习,现将 wifi 密码设置为下列数学题答案:A-1;B-2;C-3;D-4;请同学们自己作答,每两日一换。谢谢合作!!~”—— 老师们为了促进学生学习也是拼了…… 本题就要求你写程序把一系列题目的答案按照卷子上给出的对应关系翻译成 wifi 的密码。这里简单假设每道选择题都有 4 个选项,有且只有 1 个正确答案。

输入格式:

输入第一行给出一个正整数 N(≤ 100),随后 N 行,每行按照 编号-答案 的格式给出一道题的 4 个选项,T 表示正确选项,F 表示错误选项。选项间用空格分隔。

输出格式:

在一行中输出 wifi 密码。

输入样例:

8
A-T B-F C-F D-F
C-T B-F A-F D-F
A-F D-F C-F B-T
B-T A-F C-F D-F
B-F D-T A-F C-F
A-T C-F B-F D-F
D-T B-F C-F A-F
C-T A-F B-F D-F

输出样例:

13224143

思路:

找出每行的T然后匹配ABCD即可

代码:

N = int(input())
lst = ['A', 'B', 'C', 'D']
ans = ''
for i in range(N):
    t = input().split()
    for j in t:
        if j[2] == 'T':
            ans += str(lst.index(j[0])+1)
print(ans)

1077 互评成绩计算

在浙大的计算机专业课中,经常有互评分组报告这个环节。一个组上台介绍自己的工作,其他组在台下为其表现评分。最后这个组的互评成绩是这样计算的:所有其他组的评分中,去掉一个最高分和一个最低分,剩下的分数取平均分记为 G1;老师给这个组的评分记为 G2。该组得分为 (G1+G2)/2,最后结果四舍五入后保留整数分。本题就要求你写个程序帮助老师计算每个组的互评成绩。

输入格式:

输入第一行给出两个正整数 N(> 3)和 M,分别是分组数和满分,均不超过 100。随后 N 行,每行给出该组得到的 N 个分数(均保证为整型范围内的整数),其中第 1 个是老师给出的评分,后面 N−1 个是其他组给的评分。合法的输入应该是 [0,M] 区间内的整数,若不在合法区间内,则该分数须被忽略。题目保证老师的评分都是合法的,并且每个组至少会有 3 个来自同学的合法评分。

输出格式:

为每个组输出其最终得分。每个得分占一行。

输入样例:

6 50
42 49 49 35 38 41
36 51 50 28 -1 30
40 36 41 33 47 49
30 250 -25 27 45 31
48 0 0 50 50 1234
43 41 36 29 42 29

输出样例:

42
33
41
31
37
39

思路:

分别计算G1和G2,计算G2时记得判断是否在合法区间

最后答案+0.5转为int型即可

代码:

N, M = map(int, input().split())
for i in range(N):
    t = list(map(int, input().split()))
    a = []
    for j in t[1:]:
        if 0 <= j <= M:
            a.append(j)
    g2 = (sum(a)-max(a)-min(a))/(len(a)-2)
    g = (t[0]+g2)/2+0.5
    print(int(g))

1078 字符串压缩与解压

文本压缩有很多种方法,这里我们只考虑最简单的一种:把由相同字符组成的一个连续的片段用这个字符和片段中含有这个字符的个数来表示。例如 ccccc 就用 5c 来表示。如果字符没有重复,就原样输出。例如 aba 压缩后仍然是 aba

解压方法就是反过来,把形如 5c 这样的表示恢复为 ccccc

本题需要你根据压缩或解压的要求,对给定字符串进行处理。这里我们简单地假设原始字符串是完全由英文字母和空格组成的非空字符串。

输入格式:

输入第一行给出一个字符,如果是 C 就表示下面的字符串需要被压缩;如果是 D 就表示下面的字符串需要被解压。第二行给出需要被压缩或解压的不超过 1000 个字符的字符串,以回车结尾。题目保证字符重复个数在整型范围内,且输出文件不超过 1MB。

输出格式:

根据要求压缩或解压字符串,并在一行中输出结果。

输入样例 1:

C
TTTTThhiiiis isssss a   tesssst CAaaa as

输出样例 1:

5T2h4is i5s a3 te4st CA3a as

输入样例 2:

D
5T2h4is i5s a3 te4st CA3a as10Z

输出样例 2:

TTTTThhiiiis isssss a   tesssst CAaaa asZZZZZZZZZZ

思路:

压缩就判断前一个和后一个字符是否相同相同累加器就加一,不同就把字符或者个数+字符加入队列,注意首位的处理

解压就判断是否是数字,是就num=num*10+i,不是就输出一个字符或num个字符

我的老师做的数据中解压中出现了0E这种情况,虽然不违反题目的说明,但我觉得没有必要

代码:

N = input()
ans = []
t = input()
if N == 'C':
    i, num = 0, 1
    while i < len(t):
        if i == len(t)-1:
            if t[i] == t[i-1]:
                ans.append(str(num)+t[i])
            else:
                ans.append(t[i])
        else:
            if t[i] == t[i+1]:
                num += 1
            else:
                if num == 1:
                    ans.append(t[i])
                else:
                    ans.append(str(num)+t[i])
                    num = 1
        i += 1
else:
    num = 0
    f = 0
    for i in t:
        if i.isdigit():
            num = num*10+int(i)
            f = 1
        else:
            if num == 0 and f == 0:
                ans.append(i)
            else:
                for j in range(num):
                    ans.append(i)
            num = 0
            f = 0
print(''.join(ans))

1079 延迟的回文数

给定一个 k+1 位的正整数 N,写成 a**ka1a0 的形式,其中对所有 i 有 0≤a**i<10 且 a**k>0。N 被称为一个回文数,当且仅当对所有 ia**i=a**ki。零也被定义为一个回文数。

非回文数也可以通过一系列操作变出回文数。首先将该数字逆转,再将逆转数与该数相加,如果和还不是一个回文数,就重复这个逆转再相加的操作,直到一个回文数出现。如果一个非回文数可以变出回文数,就称这个数为延迟的回文数。(定义翻译自 https://en.wikipedia.org/wiki/Palindromic_number )

给定任意一个正整数,本题要求你找到其变出的那个回文数。

输入格式:

输入在一行中给出一个不超过1000位的正整数。

输出格式:

对给定的整数,一行一行输出其变出回文数的过程。每行格式如下

A + B = C

其中 A 是原始的数字,BA 的逆转数,C 是它们的和。A 从输入的整数开始。重复操作直到 C 在 10 步以内变成回文数,这时在一行中输出 C is a palindromic number.;或者如果 10 步都没能得到回文数,最后就在一行中输出 Not found in 10 iterations.

输入样例 1:

97152

输出样例 1:

97152 + 25179 = 122331
122331 + 133221 = 255552
255552 is a palindromic number.

输入样例 2:

196

输出样例 2:

196 + 691 = 887
887 + 788 = 1675
1675 + 5761 = 7436
7436 + 6347 = 13783
13783 + 38731 = 52514
52514 + 41525 = 94039
94039 + 93049 = 187088
187088 + 880781 = 1067869
1067869 + 9687601 = 10755470
10755470 + 07455701 = 18211171
Not found in 10 iterations.

思路:

从i从0循环到len(n)//2,判断n[i]==n[len(n)-1-i],只要不成立就不是回文数,0要单独考虑

先对输入进行回文数判断,是直接输出

不是就进行10次循环判断其是否是延迟回文数

代码:

def judeg(a):
    l = len(a)
    if a == '0':
        return True
    for i in range(0, l//2):
        if a[i] != a[l-1-i]:
            return False
    return True


N = input()
num = 0
if judeg(N):
    print('%s is a palindromic number.' % N)
else:
    for i in range(10):
        n = N[::-1]
        t = str(int(N)+int(n))
        print('{} + {} = {}'.format(N, n, t))
        if judeg(t):
            print('%s is a palindromic number.' % t)
            break
        N = t
    else:
        print('Not found in 10 iterations.')

1080 MOOC期终成绩

对于在中国大学MOOC(http://www.icourse163.org/ )学习“数据结构”课程的学生,想要获得一张合格证书,必须首先获得不少于200分的在线编程作业分,然后总评获得不少于60分(满分100)。总评成绩的计算公式为 G=(Gmi**dter**m×40%+Gfina**l×60%),如果 Gmi**dter**m>Gfina**l;否则总评 G 就是 Gfina**l。这里 Gmi**dter**mGfina**l 分别为学生的期中和期末成绩。

现在的问题是,每次考试都产生一张独立的成绩单。本题就请你编写程序,把不同的成绩单合为一张。

输入格式:

输入在第一行给出3个整数,分别是 P(做了在线编程作业的学生数)、M(参加了期中考试的学生数)、N(参加了期末考试的学生数)。每个数都不超过10000。

接下来有三块输入。第一块包含 P 个在线编程成绩 G**p;第二块包含 M 个期中考试成绩 Gmi**dter**m;第三块包含 N 个期末考试成绩 Gfina**l。每个成绩占一行,格式为:学生学号 分数。其中学生学号为不超过20个字符的英文字母和数字;分数是非负整数(编程总分最高为900分,期中和期末的最高分为100分)。

输出格式:

打印出获得合格证书的学生名单。每个学生占一行,格式为:

学生学号 G**p Gmi**dter**m Gfina**l G

如果有的成绩不存在(例如某人没参加期中考试),则在相应的位置输出“−1”。输出顺序为按照总评分数(四舍五入精确到整数)递减。若有并列,则按学号递增。题目保证学号没有重复,且至少存在1个合格的学生。

输入样例:

6 6 7
01234 880
a1903 199
ydjh2 200
wehu8 300
dx86w 220
missing 400
ydhfu77 99
wehu8 55
ydjh2 98
dx86w 88
a1903 86
01234 39
ydhfu77 88
a1903 66
01234 58
wehu8 84
ydjh2 82
missing 99
dx86w 81

输出样例:

missing 400 -1 99 99
ydjh2 200 98 82 88
dx86w 220 88 81 84
wehu8 300 55 84 84

思路:

用字典存储并合并三个名单,遍历字典的同时先判断作业分是否大于200,大于后计算总评成绩,然后判断总评成绩是否大于60,大于60记录一个列表

最后输出列表

代码:

P, M, N = map(int, input().split())
dic = {
     }
cnt = P+N+M
for i in range(cnt):
    xh, grade = input().split()
    if i < P:
        dic[xh] = [xh, int(grade), -1, -1, 0]
    elif i < P+M:
        if xh not in dic:
            dic[xh] = [xh, -1, int(grade), -1, 0]
        else:
            dic[xh][2] = int(grade)
    else:
        if xh not in dic:
            dic[xh] = [xh, -1, -1, int(grade), 0]
        else:
            dic[xh][3] = int(grade)
lst = []
for i in dic:
    if dic[i][1] >= 200:
        if dic[i][2] > dic[i][3]:
            dic[i][4] = int(0.4*dic[i][2]+0.6*dic[i][3]+0.5)
        else:
            dic[i][4] = dic[i][3]
        if dic[i][4] >= 60:
            lst.append(dic.get(i))
lst.sort(key=lambda x: (-x[4], x[0]))
for i in lst:
    print('%s %d %d %d %d' % (i[0], i[1], i[2], i[3], i[4]))

你可能感兴趣的:(#,PAT刷题记录)