openjudge-实用Python程序设计期末考试

目录

001好数坏数

002买手办

003字符计数

004括号内的信息

005纸币兑换硬币

006商品评分

007物资统计

008医院负荷

009矩阵换行求边缘和

010双重tag里的整数

011跳水比赛计分

012藏头诗

013打印任意年份任意月份的日历


001好数坏数

    输入一个正整数,如果是5和7的公倍数,就输出 best,如果不是7的倍数,但是是5的倍数就输出good,其它情况就输出bad。注意这些词都是小写
输入
    一个正整数n
输出
    根据要求输出best,good或bad
样例输入

    样例#1
    35
    样例#2
    14
    样例#3
    10

样例输出

    样例#1
    best
    样例#2
    bad
    样例#3
    good
n = eval(input())
if n % 35 == 0:
    print('best')
elif n % 5 == 0:
    print('good')
else:
    print('bad')

002买手办

    小明到了手办店非常开心,要大买特买。但他不是大富豪,所以只能买不超过60元手办。
    现在知道若干手办的价钱,请计算小明一共要花掉多少钱。
输入
    一行,若干个正整数,每个正整数表示一个手办的价钱
输出
    小明会买下所有不超过60元的手办。输出他将要花掉多少钱
样例输入
    120 60 60 30 50 10 100
样例输出
    210
lst=map(int, input().split())
s=0
for i in lst:
    if i<=60:
        s+=i
print(s)

003字符计数

    一个句子中有多个单词,单词之间可能有一个或多个空格。给定一个字符,请计算该字符在每个单词中的出现次数。 本题目不区分大小写字母。例如,字符A与字符a在单词Abandon中的出现次数都认为是2。 本题目有多组输入数据。
输入
    第一行一个整数n,表示数据组数;
    接下来共2n行,每两行为一组:
    每组中第一行为给定的字符,保证为小写或大写字母;
    每组中第二行为输入的句子,保证只由大小写字母或空格组成,且第一个单词前与最后一个单词后都没有空格。
输出
    n行,每行若干个整数,表示句子的每个单词中,给定字符的出现次数。
    每行的相邻整数之间用一个空格分隔。

    行末多输出了空格没有关系
样例输入
    3
    a
    Abandon that
    B
    Bob  is   the  BIG BOSS
    z
    Zelda   ZZZ

样例输出
    2 1
    2 0 0 1 1
    1 3
n=eval(input())
for i in range(n):
    s=input()
    s=s.lower()
    lst=input().split()
    for word in lst:
        word=word.lower()
        print(word.count(s),end=" ")
    print("")

004括号内的信息

程序填空
对于给定的一行字符串,输出其中每一对小括号里的信息。如果找不到配对的小括号,就输出NONE。
“配对”指的是一个左括号与其右侧最近的右括号的匹配,例如"(a)(b)"里,第一个左括号与第一个右括号配对,第二个左括号与第二个右括号配对。
本题目保证配对的小括号里一定有内容,也就是不会出现"a()b"这样的字符串。
本题目保证配对的小括号不嵌套,也就是不会出现"xy(a(bc)def)z"这样的字符串。
注意,尽管类似"123(ab)cd(ef)gh(ij)k"这样的字符串中也存在"(...(...)...)"的模式,但此时“配对”的小括号没有嵌套,因此是满足题目限制的。
输入
    第一行一个整数n,表示输入字符串行数。
    接下来n行里每行一个不包含空格的字符串s。
输出
    输出共n行,每行若干个字符串,相邻字符串间用一个空格分隔,表示每行输入字符串中各个小括号里的内容。
样例输入
    3
    1;!(#234)5@6(78)9(0)*
    0(a))(()(bcd)12
    )Nothing(

样例输出
    #234 78 0
    a ( bcd
    NONE
提示
    在正则表达式中没有分组时,re.findall返回所有匹配子串构成的列表。
    有且只有一个分组时,re.findall返回的是一个子串的列表,每个元素是一个匹配子串中分组对应的内容。
    在正则表达式中有超过一个分组时,re.findall返回的是一个元组的列表,每个元组对应于一个匹配的子串,元组里的元素,依次是1号分组、2号分组、3号分组......匹配的内容
import re
exit = 10   #此句没用
n = int(input())
#填空内容应为 pt = "XXXX",即写一个正则表达式pt

pt=r"[(](.*?)[)]"

for i in range(n):
    s = input()
    k = re.findall(pt,s)
    if k:
        for x in k:
            print(x, end = " ")
        print("")
    else:
        print("NONE")

005纸币兑换硬币

    用一张面值为x元的纸币换面值为y角、z角的硬币,每种硬币至少一枚,问有几种换法?请注意,纸币的单位是元,硬币的单位是角,一元等于10角。
输入
    输入三个正整数x、y和z
输出
    输出一个正整数,为换法的种数
样例输入
    样例#1
    1 2 5
    样例#2
    2 2 4
    样例#3
    3 4 6
样例输出
    样例#1
    0
    样例#2
    4
    样例#3
    2
提示
    枚举y、z可能枚数的全部组合
s=input().split()
x,y,z=eval(s[0]),eval(s[1]),eval(s[2])
x*=10
count=0
for i in range(1,x//y+1):
    for j in range(1,x//z+1):
        if i*y+j*z==x:
            count+=1
print(count)

006商品评分

    购物网站上有许多商品。每个商品都会得到若干用户评分(为1-10的正整数),取这些评分的平均数作为商品总评分。
给出各个商品的名称及它们对应的若干用户评分,请按照商品总评分从高到低的顺序输出商品名称;如果两个商品总评分相同,则用户评分数量多的商品排在前面。
    题目保证商品名称各不相同,且不会出现两个总评分与用户评分数量完全相同的商品。 本题目有多组输入数据。
输入
    第一行一个整数n,表示数据组数;
    接下来n组数据,每组数据中:
    第一行一个整数m,表示该组数据中商品个数;
    接下来m行,每行由一个字符串s(只含大小写字母)和若干个正整数(至多50个)组成,分别表示商品名称和用户评分。
输出
    对于每组数据,按题目要求的排序结果,每行输出一个商品名称。
样例输入
    2
    3
    Apple 10 8
    Banana 9 9 9
    Peach 10 9
    3
    Apple 10 8
    Banana 9
    Peach 9 8
样例输出
    Peach
    Banana
    Apple
    Apple
    Banana
    Peach
n=eval(input())
for i in range(n):
    m=eval(input())
    result=[]
    for j in range(m):
        lst=input().split()
        name=lst[0]
        rate=lst[1:]
        num=len(lst)-1
        ave=sum(eval(i) for i in rate)/num
        result.append([name,ave,num])
    result.sort(key=lambda x:(x[1],x[2]),reverse=True)
    for i in result:
        print(i[0])

007物资统计

    新冠肺炎肆虐全球,中国提供物资支援世界各国。现需统计世界各国总共收到的物资件数。
输入
    第一行输入一个数n,代表中国援外航班数。
    后面是n行,每行代表一个航班。
    每个航班的信息包含一个整数,表示物资数量,以及一个国名。国名不含空格。
输出
    各国的所接收到的物资总件数,按各国名称的字典序输出。
样例输入
    7
    10 USA
    20 Germany
    30 Japan
    40 Korea
    70 Japan
    20 USA
    40 Germany
样例输出
    Germany 60
    Japan 100
    Korea 40
    USA 30
n=eval(input())
d={}
for i in range(n):
    s=input().split()
    num,name=eval(s[0]),s[1]
    d[name]=d.get(name,0)+num
lst=list(d.items())
lst.sort(key=lambda x:x[0])
for i in lst:
    print(i[0],i[1])

008医院负荷

    一家医院中,同时住院的患者人数称为医院的负荷。
    卫生部门获取到了大量的病人住院/出院记录,并希望能据此统计出,在所有时刻单个医院的最大负荷是多少。
    住院记录的格式是一行两个正整数p和h,分别表示患者编号和医院编号。
    出院记录的格式是一行一个正整数p和一个-1,其中p表示患者编号。
    为简便起见,假设每家医院一开始都没有住院患者。
    题目保证,每个患者只会住院一次并至多出院一次,且任何患者在出院之前一定会在某家医院住院。(不保证记录结束时,所有患者都已出院)
    例如,对于下面的8条记录:
    1 1
    4 3
    3 1
    5 1
    8 3
    3 -1
    1 -1
    2 1
    病人住院/出院过程如下:
    ①1号患者在1号医院住院,此时1号医院负荷变为1;
    ②4号患者在3号医院住院,此时3号医院负荷变为1;
    ③3号患者在1号医院住院,此时1号医院负荷变为2;
    ④5号患者在1号医院住院,此时1号医院负荷变为3;
    ⑤8号患者在3号医院住院,此时3号医院负荷变为2;
    ⑥3号患者出院,由于3号患者之前在1号医院住院,因此1号医院负荷变为2;
    ⑦1号患者出院,由于1号患者之前在1号医院住院,因此1号医院负荷变为1;
    ⑧2号患者在1号医院住院,此时1号医院负荷变为2。
    在整个过程中,单个医院最大负荷量是3(1号医院在第4条记录时达到该负荷峰值)。
    请编写程序来计算医院的最大负荷。
输入
    本题目有多组输入数据。
    第一行一个整数n,表示输入数据的组数;
    接下来共n组数据,每组数据中:
    第一行为一个整数m,表示该组数据中住院/出院记录的条数;
    接下来m行,每行为一条住院/出院记录,格式如上所述。
输出
    对每组输入数据,输出一个整数,表示单个医院曾经达到的最大负荷
样例输入
    2
    8
    1 1
    4 3
    3 1
    5 1
    8 3
    3 -1
    1 -1
    2 1
    1
    1 2
样例输出
    3
    1

做题思路:

这题需要在新输入数据的同时,统计当前医院最大住院人数。

因此创建一个result字典,key是医院h,value是个列表lst,列表里面是所有当前住院病人p。

接收输入数据时进行判断,如果h>0,把对应p加进列表lst,并把lst更新到result字典里。

如果h==-1,代表病人出院,在字典的value里,也就是病人列表lst里,寻找对应病人p,把p移除。

与此同时,统计每个value对应lst长度,也就是每个医院对应的病人人数,添加到另一个列表l里面,计算l里元素最大值,就是此时医院的最大负荷。

把最大值赋值给maxn,每个输入数据时都进行更新maxn,最后输出maxn,就是医院最大负荷。

n = eval(input())
for i in range(n):
    maxn = 0
    result = {}
    m = eval(input())
    for j in range(m):
        s = input().split()
        p, h = eval(s[0]), eval(s[1])
        if h > 0:
            if h not in result.keys():
                result[h]=result.get(h,[])
            lst=result[h]
            lst.append(p)
            result[h]=lst
        elif h==-1:
            for value in result.values():
                if p in value:
                    value.remove(p)
        l=[]
        for value in result.values():
            l.append(len(value))
        maxd = max(l)
        maxn = max(maxn, maxd)
    print(maxn)

009矩阵换行求边缘和

    输入一个整数矩阵,交换其中的两行,然后计算位于矩阵边缘的元素之和。所谓矩阵边缘的元素,就是第一行和最后一行的元素以及第一列和最后一列的元素。
输入
    第一行分别为矩阵的行数m和列数n(m < 100,n < 100),两者之间以一个空格分开。
    接下来输入的m行数据中,每行包含n个整数,整数之间以一个空格分开。
    在接下来是两个整数x,y,表示需要将矩阵的第x行和第y行交换一下。
输出
    输出交换行之后的矩阵的边缘元素和
样例输入
    3 3
    3 4 1
    3 7 1
    2 0 1
    1 2
样例输出
    18
m,n=map(int,input().split())
lst=[]
for i in range(m):
    num=list(map(int,input().split()))
    lst.append(num)
x,y=map(int,input().split())
t=lst[x-1]
lst[x-1]=lst[y-1]
lst[y-1]=t
s=sum(lst[0])+sum(lst[-1])
for i in range(1,m-1):
    s+=(lst[i][0]+lst[i][-1])
print(s)

010双重tag里的整数

tag是形如"A"的字符串,X是一个长度不为0且不超过5的字符串,由大小写字母构成。
    "" 和 ""里面的X必须相同。
    例如:
    xyd 是一个tag
    但是  xyd 不是一个tag。
    双重tag形式如下:
    "ABC"
    X,Y都是一个长度不为0且不超过5的字符串,由大小写字母构成。
    "" 和 ""里面的X必须相同,
    ""和""里面的Y必须相同。
    "B"称为内重tag。""只和离他最近的""构成内重tag。
    A,B,C是任意长度不为0的字符串。
    请找出B中的全部不超过4位的整数。00003 算超过4位。
输入
    若干行。数据保证一个tag内部最多只有一个tag
输出
    对每行,依次输出双重tag中的所有不超过4位且没有前导0的整数。单个的0算没有前导0。如果找不到,就输出NONE
样例输入
    bacbb123aaa 292 bbb 384 j 67477 0 dd 04 05hdc12cdef
    k112 3578d3 4kdef
    k112 3578d3 4kdef
    k112 3578d3 4def
    k112 3578d3 4def
    k112 3578d3 4def

样例输出
    292 384 0
    12 35 3 4
    12 35 3 4
    12 35
    12 35
    NONE
提示
    读入若干行,需要用 try...except 来判断结束

做题思路:

用re从外向里分次匹配,第一次匹配最外面一层" ",结果为lst。

如果lst不为空,for循环对结果里的每个子串进行再第二次匹配B,结果为nlst。

再判断nlst不为空时,最后一层for循环,匹配B中的全部整数,结果为result。

result不为空时,判断所有不超过4位且没有前导0的整数,或者单个的0,并输出,以空格结尾。

v是判断结果是否为空的变量,如果结果不为空,v=1,进行换行。

如果结果为空,v=0,输出NONE。

import re

while True:
    try:
        s = input()
        m = "<([A-Za-z]{1,5})>(.*)"
        lst = re.findall(m, s)
        # print('第1次',lst,type(lst))
        v = 0
        if lst:
            for i in lst:
                s = i[1]
                # print('第1次',s,type(s))
                m = ".<([A-Za-z]{1,5})>(.*?)."
                nlst = re.findall(m, s)
                if nlst:
                    # print('第2次',nlst)
                    for j in nlst:
                        s = j[1]
                        m = "(\d+)"
                        # print(s,type(s))
                        result = re.findall(m, s)
                        if result:
                            # print(result)
                            for n in result:
                                if n == '0' or (len(n) < 5 and n[0] != '0'):
                                    print(n, end=" ")
                                    v = 1
        if v == 1:
            print("")
        else:
            print("NONE")
    except:
        break

011跳水比赛计分

 有若干个同学参加跳水比赛,每个同学都有若干位老师给他打分。 一共有m条打分记录,每一条记录的格式都是这样的:"id score",
表示编号为id的同学获得了score分。(id和score都是正整数) 现在这m条记录依次送到了你的手上,你想在每一条记录到达的时候,
都快速地计算出这个编号为id的同学目前得到的平均分是多少。平均只取整数部分即可,小数部分直接去掉,不要四舍五入。
输入
    第一行,一个整数m。(m <= 100000)
    接下来m行,每行两个正整数代表id和score.
输出
    对每行的 id score, 输出id同学到目前为止的平均分
样例输入

    4
    1 100
    2 90
    2 95
    1 70
样例输出
    100
    90
    92
    85
m=eval(input())
d={}
for i in range(1,m+1):
    s=input().split()
    id,score=eval(s[0]),eval(s[1])
    if id not in d.keys():
        d[id]=[1,score]
    else:
        d[id][0]+=1
        d[id][1]+=score
    ave=d[id][1]//d[id][0]
    print(ave)

012藏头诗

    雍正皇帝不能忍受任何人说清朝或者他坏话,以至于他大兴文字狱。因此老百姓书写任何东西都得很小心。诗人写诗也得担心。一些诗人发明了一种奇怪写诗方法,只有TA们朋友圈的人才能看懂。这样的诗统称为藏头诗。

    一首藏头诗,是一个N×N 的字符矩阵,看起来杂乱无章没啥意思。但是,如果你用特定的顺序读这些字符,你就能看懂。正确的阅读顺序如下面左图所示:


    顺着箭头读,你会看到“THISISAVERYGOODPOEMITHINK”,这就有点意思了。

    过了一段时间后,诗人们发现,雍正的杀手,血滴子,也学会了读这样的诗。这很危险。所以诗人们发明了新的写诗顺序,如上面右图所示。

    诗人想把所有的老写法的诗,都转成新写法的诗歌。请你帮助TA们。

输入
    一共不超过10组数据。
    在每组数据里:
    第一行是一个整数N ( 1 <= N <= 100), 表明诗是一个N×N 的字符矩阵,仅包含大写字母。
    接下来是N行。每行是一个N个字符的字符串。这N行表示一首老写法的诗。
输出
    对每组数据,输出新写法的诗。
样例输入
    5
    THSAD
    IIVOP
    SEOOH
    RGETI
    YMINK
    2
    AB
    CD
    4
    ABCD
    EFGH
    IJKL
    MNOP

样例输出
    THISI
    POEMS
    DNKIA
    OIHTV
    OGYRE
    AB
    DC
    ABEI
    KHLF
    NPOC
    MJGD

做题思路:

1.定义一个函数topoem,把输入的矩阵数据还原成诗,返回一个字符串poem。

2.再定义一个函数result,把poem转换成新的矩阵,返回一个二维列表。

3.最后把二维列表按行输出即可。

写topoem这个函数花了很久时间,思维总卡住,最后按最笨的方法一个个拆解写到草稿上,再按规律形成循环。

如果N=5,是奇数,列表下标还原顺序应该是00,01,10,   20,11,02,   03,12,21,30,    40,31,22,13,04,    14,   23,32,41,    42,33,24,    34,43,44。

分析下标变化的规律。首先设定字符串poem初始值为lst[0][0],然后一个for循环,做一个到矩阵对角线的三角形。从1-N(N=5),i的取值分别为1,2,3,4。

此时进入while循环,设定两个迭代变量a,b,a从0开始,一直递增到i为止;b从i开始,一直递减到0。a或者b只要其中一者先到顶,该次循环就停止,进入下一个循环。

当i是奇数时,lst下标为ab,当i是偶数,lst下标是ba,把lst对应字符依次累加到字符串poem。

顺序如下:

i=1,ab=01,10;i=2,ba=20,11,02;i=3,ab=03,12,21,30;i=4,ba=40,31,22,13,04。

当i循环到最后,第一个三角形完成,要进行另一半三角形。

此时做一个N的奇偶if判断,因为奇偶数不同的矩阵排列顺序不同。

一个for循环从1到n-1,i取值分别是1,2,3,再进入while循环,a从i开始递增到n-1,b从n-1即4开始递减。

如果N是奇数,当i是奇数时,按照下标ab累加,i是偶数时,按照下标ba累加。

如果N是偶数,当i是奇数时,按照下标ba累加,i是偶数时,按照下标ab累加。

最后加上lst[n-1][n-1],完成poem字符串。

在函数result里,要把字符串按照回形顺序形成新的矩阵,第一行--最后一列--最后一行--第一列,第二行--倒数第二列--倒数第二行--第二列……

因此有个while循环,里面有4个for循环,每完成一个回形,就进入下一个while循环。

最后剩下一个字符,是矩阵最中心的字符,完成新矩阵。

# coding:utf-8


def topoem(lst, n):
    if n == 0:
        return lst[0][0]
    else:
        poem = lst[0][0]
        for i in range(1, n):
            a, b = 0, i
            if i % 2:
                while a <= i and b >= 0:
                    poem += lst[a][b]
                    a += 1
                    b -= 1
            else:
                while a <= i and b >= 0:
                    poem += lst[b][a]
                    a += 1
                    b -= 1
        if n%2:
            for i in range(1, n - 1):
                a, b = i, n - 1
                if i % 2:
                    while a <= n - 1:
                        poem += lst[a][b]
                        a += 1
                        b -= 1
                else:
                    while a <= n - 1:
                        poem += lst[b][a]
                        a += 1
                        b -= 1
        else:
            for i in range(1, n - 1):
                a, b = i, n - 1
                if i % 2:
                    while a <= n - 1:
                        poem += lst[b][a]
                        a += 1
                        b -= 1
                else:
                    while a <= n - 1:
                        poem += lst[a][b]
                        a += 1
                        b -= 1
        poem += lst[n - 1][n - 1]
    return poem

def result(s,n):
    lst=[[i for i in range(n)] for j in range(n)]
    t=0
    a=0
    b=n-1
    while a

013打印任意年份任意月份的日历

    给定公元year年month月,打印该月月历
输入
    第一行一个输入整数n,表示有n组数据。
    后面n行,每行一组数据,是两个整数,分别代表year( 0 < year <= 100000)和month(数据合法,1<=month<=12),用空格隔开
输出
    对于每组数据:
    第一行输出月份(英文表示,首字母大写)和年份,用逗号隔开;
    第二行输出星期几, Sun Mon Tue Wed Thu Fri Sat,用\t隔开;
    接下来输出当月日期,日期用\t隔开,第一周缺天直接输出\t。
    (行与行之间无空行,每组数据之间无空行)
    行末多出来\t没有关系
    12个月份的单词是:
    "January","February", "March", "April", "May", "June", "July", "August", "September", "October","November", "December"
样例输入
    3
    2019 12
    403 5
    23456 7

样例输出
    

做题思路:

之前作业万年历的题目是,给定年月日,求星期几。此题在之前基础上,确认每月1日是星期几,然后输入对应数量\t,之后按照该月份天数,以此输出日期,逢七换行。

def monthday(year, month):
    days = 31
    if month == 2:
        if year % 400 == 0 or year % 4 == 0 and year % 100 != 0:
            days = 29
        else:
            days = 28
    elif month in (4, 6, 9, 11):
        days = 30
    return days
def check(y, m, d):
    if not 1 <= m <= 12:
        print('Illegal')
        return 0
    if m in (1, 3, 5, 7, 8, 10, 12):
        if not 1 <= d <= 31:
            print('Illegal')
            return 0
    elif m == 2:
        if y % 400 == 0 or y % 4 == 0 and y % 100 != 0:
            if not 1 <= d <= 29:
                print('Illegal')
                return 0
        else:
            if not 1 <= d <= 28:
                print('Illegal')
                return 0
    else:
        if not 1 <= d <= 30:
            print('Illegal')
            return 0
n=eval(input())
for i in range(n):
    s=input().split()
    y,m=eval(s[0]),eval(s[1])
    monthlst=['January','February','March','April','May','June','July','August','September','October','November','December']
    weekdaylst=['Sun','Mon','Tue','Wed','Thu','Fri','Sat']
    print(f"{monthlst[m-1]},{y}")
    print('\t'.join(weekdaylst))

    d, days = 1, 0
    monthDays = [-1, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]
    weekdays = [6, 0, 1, 2, 3, 4, 5]
    if y % 400 == 0 or y % 4 == 0 and y % 100 != 0:
        monthDays[2] = 29
    if check(y, m, d) == 0:
        continue
    if y < 2000:
        c = -1
    elif y > 2000:
        c = 1
    if y < 2000:
        for i in range(y, 2000):
            if i % 400 == 0 or i % 4 == 0 and i % 100 != 0:
                days += 366
            else:
                days += 365
    elif y > 2000:
        for i in range(2000, y):
            if i % 400 == 0 or i % 4 == 0 and i % 100 != 0:
                days += 366
            else:
                days += 365
    md = 0
    for month in range(1, m):
        md += monthDays[month]
    if y < 2000:
        days -= md
    else:
        days += md
    if y < 2000:
        days -= d - 1
        days = - days
    else:
        days += (d - 1)
    days %= 7
    if days < 0:
        week=weekdays[7 - days]
    elif days >= 0:
        week=weekdays[days]
    for i in range(week):
        print('',end='\t')
    for i in range(1,monthday(y,m)+1):
        print(i,end="\t")
        if (i+week)%7==0 and i

 

你可能感兴趣的:(python)