一.单选题

2-1.下面定义字典的语句那个是正确的?

A.
momthdays=dict(Jan=31,Feb=28,Mar=31,Apr=30)

B.
momthdays=dict("Jan"=31,"Feb"=28,"Mar"=31,“Apr"=30)

C.
momthdays={Jan:31,Feb:28,Mar:31,Apr:30}

D.
momthdays={Jan=31,Feb=28,Mar=31,Apr=30}

答案:A

解析:在选项 B 中,字典的键应该使用引号括起来,因此应该是 {"Jan":31, "Feb":28, "Mar":31, "Apr":30}。

在选项 C 中,键应该是字符串类型,需要使用引号括起来,因此应该是 {"Jan":31, "Feb":28, "Mar":31, "Apr":30}。

在选项 D 中,应该使用冒号来分隔键和值,因此应该是 {"Jan":31, "Feb":28, "Mar":31, "Apr":30}。


2-2.已知x=[1, 2, 3],y=[4, 5],则x.extend(y)后,x的值是()。

A.
[1, 2, 3, 4, 5]

B.
[[1, 2, 3], [4, 5]]

C.
[[1, 2, 3], 4, 5]

D.
[1, 2, 3, [4, 5]]
答案:A

解析:extend 是一个列表对象的方法,用于在原列表的末尾一次性添加另一个列表中的多个元素。

它将另一个列表中的元素添加到原列表的末尾,如果被添加的元素是一个列表,它将不会把整个列表当成一个元素,而是将这个列表中的每一个元素分别添加到原列表中。

例如,假设有两个列表 a = [1, 2, 3] 和 b = [4, 5],执行 a.extend(b) 后,a 的值将变成 [1, 2, 3, 4, 5]。


2-3.执行下面语句的结果是()

dict = {'Name': 'Zara', 'Age': 7, 'Name': 'Manni'}
dict.pop('Name')
dict['Add']='Shanghai'
dict.popitem()
print(dict)

A.
{}

B.
{'Age': 7}

C.
{'Name': 'Zara', 'Age': 7}

D.
{'Age': 7, 'Name': 'Manni'}

答案:B


解析:第1行:定义了一个字典dict,其中键Name的值为'Zara',键Age的值为7,但是在后面键Name的值被修改为'Manni',因此最终字典中只有一个键值对{'Name': 'Manni', 'Age': 7}。

第2行:调用pop方法删除键为'Name'的键值对,但是由于之前已经修改过键'Name'对应的值了,因此实际上是删除了键'Name'对应的键值对{'Name': 'Manni'}。

第3行:向字典dict中添加一个键为'Add',值为'Shanghai'的键值对,此时字典内容为{'Age': 7, 'Add': 'Shanghai'}。

第4行:调用popitem方法弹出一个键值对,由于字典是无序的,弹出的键值对可以是任意一个键值对,因此可能输出{'Add': 'Shanghai'}或者{'Age': 7}。

因此,正确的输出结果是{'Age': 7},选项B正确。


2-4.现有一列表animal = ["cat", "dog", "tiger"],以下哪个操作不能正确输出列表中的所有元素?``

A.
for i in animal:

print(i, end=" ")

B.
for i in range(len(animal)):
print(animal[i], end=" ")

C.
for i in range(3):
print(animal[i], end=" ")

D.
for i in range(animal):
print(i, end=",")

答案:D


解析:range()中只能包含int类型的数据,而animal是列表类型的,会导致报错


2-5.表达式[1,2,3]*3的执行结果是( )。

A.
[1,2,3,1,2,3,1,2,3]

B.
[3,6,9]

C.
[1,8,27]

D.
语法错误

答案:A


2-6.a=[2,3,4,1,6,9,8],执⾏b = [index for index, value in enumerate(a) if value > 3]后,b=( )。

A.
[(2,4),(4,6),(5,9),(6,8)]

B.
[3,5,6,7]

C.
[4,6,9,8]

D.
[2,4,5,6]

答案:D


题目描述中的代码b = [index for index, value in enumerate(a) if value > 3]的含义是:在列表a中寻找所有大于3的元素,并将这些元素所对应的下标放入列表b中。


2-7.当已存在一个abc.txt文件时,执行函数open("abc.txt","r+")的功能是( )。

A.
打开abc.txt文件,清除原有的内容

B.
打开abc.txt文件,只能写入新的内容

C.
打开abc.txt文件,只能读取原有的内容

D.
打开abc.txt文件,可以读取和写入新的内容

答案:D


2-8.下列方法中,用于向文件中写内容的是( )。

A.
open

B.
write

C.
close

D.
read

答案:B


2-9.二维列表ls=[[1,2,3], [4,5,6],[7,8,9]],以下选项中能获取其中一个维度的数据是‪‬‪‬‪‬‪‬‪‬‮‬‫‬‪‬‪‬‪‬‪‬‪‬‪‬‮‬‫‬‮‬‪‬‪‬‪‬‪‬‪‬‮‬‭‬‪‬‪‬‪‬‪‬‪‬‪‬‮‬‭‬‫‬‪‬‪‬‪‬‪‬‪‬‮‬‭‬‪‬( )。

A.
ls[-1][ –1]

B.
ls[-1]

C.
ls[1][1]

D.
ls[-2][-1]

答案:B


解析:选项B可以获取二维列表ls的一个维度数据,即获取整个子列表[7,8,9],因为ls[-1]表示列表ls的最后一个子列表。其他选项分别表示获取ls中指定位置的元素,而不是获取整个子列表。


2-10.下面不属于Python文件操作方法的是()。

A.
read( )

B.
write( )

C.
join( )

D.
readline( )

答案:C


解析:join() 不属于Python文件操作方法,它是字符串的方法,用于将序列中的元素以指定的字符连接生成一个新的字符串。




二.程序填空题

5-1.程序流程:输入货币-货币转换-货币输出。已知人民币兑换美元的汇率为6.8833,美元兑换人民币的汇率为0.1452。人民币对应符号为¥,美元对应符号为$。要求输出结果保留三位小数。

输入样例:
34¥
输出样例:
Dollar:4.937
请将以下程序补充完整:
mWorth = input()
if mWorth _ in ['$']:
CNY = (eval(mWorth __
))6.8833
print('RMB:__' % CNY)
elif mWorth __in ['¥']:
USD = (eval(mWorth ____))
0.1452
print('Dollar:____' % USD)
else:
print("enter the error message")



答案:[-1]
[:-1]
%.3f
[-1]
[:-1]
%.3f




5-2.函数repeat(ls)判定列表ls中是否包含重复元素,如果包含返回True,否则返回False。每一个列表中只要有一个元素出现两次,那么该列表即被判定为包含重复元素。

然后使用该函数对n行字符串进行处理。最后统计包含重复元素的行数与不包含重复元素的行数。

输入格式:
输入n,代表接下来要输入n行字符串。
然后输入n行字符串,字符串之间的元素以空格间隔。

输出格式:
True=包含重复元素的行数, False=不包含重复元素的行数。

其中逗号后面有空格。

输入样例:
5
1 2 3 4 5
1 3 2 5 4
1 2 3 6 1
1 2 3 2 1
1 1 1 1 1
输出样例:
True=3, False=2
def repeat(ls):
s=set(ls)


return False
else:
return True

n=int(input())
countT=countF=0
for i in range(n):


countT+=1
else:
countF+=1
print(_____)


答案:if len(ls)==len(s):
if repeat(input().split()):
"True={}, False={}".format(countT,countF)



解析:def repeat(ls): 这一代码块主要判断是否重复并返回相应的值,set()函数可以实现去重操作。if repeat(input().split()):这一代码主要是接受一组输入并输入给repeat()这一代码块判断是否重复,从而实现程序的功能。


5-3.本题目要求输入一行整数,采用选择排序的方法进行排序后输出。

def SelectionSort(a):
n = len(a)
for i in range(n-1):


for j in__
if ___ :



lst = list(map(int,input().split()))
SelectionSort(lst)
print(lst)


答案:min_index = i
range(i+1, n)
a[j] < a[min_index]
min_index = j
a[i], a[min_index] = a[min_index], a[i]



解析:选择排序的思想是从未排序序列中找到最小元素,然后将其放到序列的起始位置,再从剩余未排序元素中继续寻找最小元素,然后放到已排序序列的末尾。以此类推,直到所有元素均排序完毕。


5-4.以下程序用于实现以下计算:

一年一度的校园好声音进行到了激烈的决赛环节,8位评委对入围的6位选手给出了最终的评分。请根据评分表,将每位选手的得分去掉一个最高分和一个最低分后求平均分(保留2位小数),并按照平均分由高到低的顺序输出选手编号和最后得分。

可用以下输入输出样例测试程序是否正确

输入样例:
本题没有输入

输出样例:
选手037最后得分95.67
选手066最后得分94.83
选手020最后得分93.0
选手005最后得分92.5
选手108最后得分91.17
选手012最后得分88.67
请复制以下代码在IDLE中完成填写并调试,正确后再填入本题空白处。

scores={"012":(90,94,97,86,85,89,88,85),
"005":(91,91,92,98,90,96,90,95),
"108":(96,86,97,96,87,86,86,96),
"037":(95,95,94,93,97,98,99,95),
"066":(95,87,94,94,93,99,96,97),
"020":(89,97,91,95,89,94,97,92)}
average={}
for k,v in scores.items():
average[k]=__
ls=[__]
ls.sort(__)
for __ :
print("选手{}最后得分{}".format(x[1],x[0]))


答案:round((sum(v)-max(v)-min(v))/6,2)
(v,k) for k,v in average.items()
reverse=True
x in ls



解析:for k, v in scores.items(): 是一个循环语句,用于遍历字典 scores 中的所有键值对。其中,k 是字典 scores 的键,v 是字典 scores 的值,即选手的评分。在循环中,可以通过 k 来访问选手的编号,通过 v 来访问选手的评分元组。
average[k]=round((sum(v)-max(v)-min(v))/6,2) 这行代码计算了每个选手的得分平均值,并将结果存储在字典average中。其中,k表示选手编号,v表示该选手的得分列表,sum(v)计算该选手得分的总和,max(v)和min(v)分别计算该选手得分中的最高分和最低分,再将它们从总和中减去,最终得到去掉一个最高分和一个最低分后的总分数。由于每个选手只有6个得分,因此要除以6得到平均分,并使用round函数将结果保留两位小数。
然后,代码使用列表推导式构建了 ls 列表。对于字典 average 的每一个键值对,即选手编号和该选手的平均分数,使用元组 (v,k) 表示该选手的平均分数 v 和选手编号 k,并将这个元组添加到 ls 列表中。最后使用 sorted 函数对 ls 列表按照元组的第一个元素(即平均分数)进行排序。




三.编程题

7.1 菱形

输入一个整数n,输出2n-1行构成的菱形,例如,n=5时的菱形如输出样例所示。

输入格式:
测试数据有多组,处理到文件尾。每组测试输入一个整数n(3≤n≤20)。

输出格式:
对于每组测试数据,输出一个共2n-1行的菱形,具体参看输出样例。

输入样例:
5
输出样例:

    *
   ***
  *****
 *******
*********
 *******
  *****
   ***
    *




代码示例:

while True:
    try:
        n=int(input())
        for i in range(1,n+1):
            print(' '*(n-i)+'*'*(2*i-1))
        for i in range(1,n):
            print(' '*i+'*'*(2*(n-i)-1))
    except:
        break



代码解析:首先,使用 while True 和 try-except 结构来处理多组测试数据的输入。

对于每个 n,先输出上半部分的菱形,即从第一行到第 n 行,每行由空格和星号组成。对于第 i 行,需要先输出 n-i 个空格,再输出 2i-1 个星号。

然后输出下半部分的菱形,即从第 n+1 行到第 2n-1 行,每行由空格和星号组成。对于第 i 行,需要先输出 i 个空格,再输出 2(n-i)-1 个星号。

最后,使用 input() 函数来获取输入数据,并将其转换为整数。





7-2.三七二十一

某天,诺诺看到三七二十一(3721)数,觉得很神奇,这种数除以3余2,而除以7则余1。例如8是一个3721数,因为8除以3余2,8除以7余1。现在给出两个整数a、b,求区间[a,b]中的所有3721数,若区间内不存在3721数则输出“none”。

输入格式:
首先输入一个正整数T,表示测试数据的组数,然后是T组测试数据。每组测试输入两个整数a,b(1≤a<b<2000)。

输出格式:
对于每组测试,在一行上输出区间[a,b]中所有的3721数,每两个数据之间留一个空格。如果给定区间不存3721数,则输出“none”(引号不必输出)。

输入样例:
2
1 7
1 100
输出样例:
none
8 29 50 71 92
来源:
[1] 黄龙军, 等. 大学生程序设计竞赛入门—C/C++程序设计(微课视频版), 北京:清华大学出版社, 2020.11. ISBN:9787302564744
[2] 黄龙军.程序设计竞赛入门(Python版),北京:清华大学出版社,2021.4. ISBN:9787302571230


代码示例:

T = int(input())

for i in range(T):
    a, b = map(int, input().split())
    ans = []
    for j in range(a, b+1):
        if j % 3 == 2 and j % 7 == 1:
            ans.append(j)
    if len(ans) == 0:
        print("none")
    else:
        print(" ".join(str(x) for x in ans))





7-3 求π的近似值

用公式求π的近似值:π²/6=1+1/2²+1/3²+1/4²+。。。
当求和项小于误差时,结束求和。

输入格式:
在一行输入误差范围

输出格式:
在一行输出π的近似值(保留6位小数)。

输入样例:
在这里给出一组输入。例如:

0.00000001
输出样例:
在这里给出相应的输出。例如:

3.141497


代码示例

import math

error = float(input())
pi = 0
i = 1

while True:
    pi += 1 / (i ** 2)
    i += 1
    if 1 / (i ** 2) < error:
        break

pi *= 6
pi = math.sqrt(pi)
print("%.6f" % pi)



代码解析:代码的思路是利用了题目中给出的公式,通过不断累加求和项,直到误差小于给定的值为止。在每次循环中,我们判断当前的求和项是否小于误差,如果是,则退出循环。最后,我们将计算出来的和乘以6再开平方根,得到π的近似值,并输出保留6位小数的结果。




7-4 学车费用

小明学开车后,才发现他的教练对不同的学员收取不同的费用。
小明想分别对他所了解到的学车同学的各项费用进行累加求出总费用,然后按下面的排序规则排序并输出,以便了解教练的收费情况。排序规则:
先按总费用从多到少排序,若总费用相同则按姓名的ASCII码序从小到大排序,若总费用相同而且姓名也相同则按编号(即输入时的顺序号,从1开始编)从小到大排序。

输入格式:
测试数据有多组,处理到文件尾。每组测试数据先输入一个正整数n(n≤20),然后是n行输入,第i行先输入第i个人的姓名(长度不超过10个字符,且只包含大小写英文字母),然后再输入若干个整数(不超过10个),表示第i个人的各项费用,数据之间都以一个空格分隔,第i行输入的编号为i。输入数据和结果均在32位int型范围之内。

输出格式:
对于每组测试,在按描述中要求的排序规则进行排序后,按顺序逐行输出每个人费用情况,包括:费用排名(从1开始,费用相同则排名也相同)、编号、姓名、总费用。每行输出的数据之间留1个空格。

输入样例:
3
Tom 2800 900 2000 500 600
Jack 3800 400 1500 300
Tom 6700 100
3
Tom 2800 400 100
Jack 3800 800
mary 3300

输出样例:
1 1 Tom 6800
1 3 Tom 6800
3 2 Jack 6000
1 2 Jack 4600
2 1 Tom 3300
2 3 mary 3300
来源:
[1] 黄龙军, 等. 大学生程序设计竞赛入门—C/C++程序设计(微课视频版), 北京:清华大学出版社, 2020.11. ISBN:9787302564744
[2] 黄龙军.程序设计竞赛入门(Python版),北京:清华大学出版社,2021.4. ISBN:9787302571230


代码示例:

while True:
    try:
        n = int(input())
        students = []
        for i in range(n):
            line = input().split()
            name, fees = line[0], list(map(int, line[1:]))
            total_fees = sum(fees)
            students.append([name, total_fees, i+1])
        students.sort(key=lambda x: (-x[1], x[0], x[2]))
        rank = 1
        for i, s in enumerate(students):
            if i > 0 and s[1] < students[i-1][1]:
                rank = i+1
            print(rank, s[2], s[0], s[1])
    except EOFError:
        break



代码解析:首先,使用一个空列表students来存储学生信息,每个学生信息包括姓名、编号和总费用。通过输入来获取学生信息,并将其加入到students列表中。

然后,使用sort()方法对学生信息进行排序。sort()方法可以接受一个key参数,该参数是一个函数或 lambda 表达式,用于指定排序的规则。在本题中,我们需要先按总费用从高到低排序,如果总费用相同,则按姓名的 ASCII 码从小到大排序,如果总费用和姓名都相同,则按编号从小到大排序。

对于sort()方法的参数key,我们使用 lambda 表达式定义排序规则。lambda 表达式可以在一行代码中表示一个简单的函数。例如,(lambda x: x[2])表示一个函数,输入参数为一个列表x,返回值为列表x的第三个元素。key=lambda x: (-x[2], x[0], x[1])表示按照总费用从高到低排序,如果总费用相同,则按姓名的 ASCII 码从小到大排序,如果总费用和姓名都相同,则按编号从小到大排序。

最后,我们使用enumerate()函数和print()语句输出每个学生的费用情况。enumerate()函数可以在迭代一个可遍历的对象时,返回每个元素的索引和值。在本题中,我们需要输出每个学生的费用排名、编号、姓名和总费用。我们使用一个计数器rank来记录当前的费用排名,如果当前学生的总费用和前一个学生的总费用不同,那么费用排名就加1,否则费用排名不变。




7-5 词频统计-基础题

请编写程序,对一段文本(不带符号),统计其中所有不同单词的个数,以及词频最大的前5个词。

输入格式:
输入给出一段非空文本,可以是中文或者英文,词间空格或分行隔开。

输出格式:
输出词的总数和词频最大的前5个词。注意“不区分英文大小写,例如“PAT”和“pat”被认为是同一个词。

随后按照词频递减的顺序,按照“单词:词频”的格式输出词频最大的前5个词。若有并列,则按递增字典序输出。

输入样例1:
在这里给出一组输入。例如:

This is a test
so is considered as the same as long

But this_8 is different than this
输出样例1:
在这里给出相应的输出。例如:

14
is:3
as:2
this:2
a:1
but:1
输入样例2:
在这里给出一组输入。例如:

双儿 洪七公 赵敏 赵敏 逍遥子 鳌拜 殷天正 金轮法王 乔峰 杨过 洪七公 郭靖
杨逍 鳌拜 殷天正 段誉 杨逍 慕容复 阿紫 慕容复 郭芙 乔峰 令狐冲 郭芙
金轮法王 小龙女 杨过 乔峰 杨逍 乔峰 慕容复
输出样例2:
在这里给出相应的输出。例如:

17
乔峰:4
慕容复:3
杨逍:3
杨过:2
殷天正:2



代码示例

import sys
from collections import Counter

text = []
for line in sys.stdin:
    text += line.strip().lower().split()

word_counts = Counter(text)
total_count = len(word_counts)

top_five = sorted(word_counts.items(), key=lambda x: (-x[1], x[0]))[:5]

print(total_count)
for word, count in top_five:
    print(f"{word}:{count}")



代码解析:导入必要的库
sys 和 collections.Counter 都是 Python 标准库中的模块,分别用于处理系统相关的操作和集合类相关的操作。

sys 模块提供了与 Python 解释器和宿主环境(例如操作系统)交互的功能。其中 sys.stdin 可以用于读取标准输入流,sys.stdout 可以用于向标准输出流写入内容,sys.argv 可以获取命令行参数等。更多内容请参考官方文档:https://docs.python.org/3/library/sys.html

collections.Counter 是一个用于计数的容器,它可以统计元素出现的次数。通过它可以轻松实现统计词频的功能。更多内容请参考官方文档:https://docs.python.org/3/library/collections.html#collections.Counter

import sys
from collections import Counter

读入文本并统计词频

text = []
for line in sys.stdin:
    text += line.strip().lower().split()

word_counts = Counter(text)

首先定义一个空列表 text 存储读入的文本,然后使用 sys.stdin 逐行读入,使用 strip() 方法去除行末的空白字符,使用 lower() 方法将每个单词转换为小写字母,使用 split() 方法将每行的单词切分,并将切分结果存入 text 列表中。

然后使用 Counter 类统计 text 中每个单词出现的次数,并将结果保存到 word_counts 变量中。

输出总单词数和词频最高的前五个单词

total_count = len(word_counts)

top_five = sorted(word_counts.items(), key=lambda x: (-x[1], x[0]))[:5]

print(total_count)
for word, count in top_five:
    print(f"{word}:{count}")

首先输出单词总数,即 word_counts 中不同单词的个数,使用 len() 函数计算即可。

然后使用 sorted() 函数对 word_counts.items() 进行排序,按照单词出现次数降序排列,如果出现次数相同则按照字典序升序排列。排序的 key 参数使用了一个 lambda 表达式,其中 -x[1] 表示按照出现次数的相反数进行排序(因为要降序排列),x[0] 表示在出现次数相同的情况下按照单词字典序升序排列。

最后取前五个元素并输出,格式为 单词:出现次数,其中单词使用小写字母表示。




7-6 按日期排序

输入若干日期,按日期从小到大排序。

输入格式:
本题只有一组测试数据,且日期总数不超过100个。按“MM/DD/YYYY”的格式逐行输入若干日期。

输出格式:
按“MM/DD/YYYY”的格式输出已从小到大排序的各个日期,每个日期占一行。

输入样例:
12/31/2005
10/21/2003
02/12/2004
11/12/1999
10/22/2003
11/30/2005
输出样例:
11/12/1999
10/21/2003
10/22/2003
02/12/2004
11/30/2005
12/31/2005
出处:
ZJUTOJ 1045



代码示例

from datetime import datetime

dates = []
while True:
    try:
        date_str = input().strip()
    except:
        break
    dates.append(datetime.strptime(date_str, '%m/%d/%Y'))

dates.sort()

for date in dates:
    print('{}/{}/{}'.format(date.strftime('%m').zfill(2),
                             date.strftime('%d').zfill(2),
                             date.year))




代码解析:
当输入完所有日期后,我们将日期字符串转换成 datetime 类型并放入一个列表 dates 中。然后我们对日期列表进行排序,排序后的日期列表中的日期是按照从小到大的顺序排列的。

最后,我们使用 strftime 方法对日期进行格式化,输出格式要求按照 MM/DD/YYYY 的格式,其中 strftime('%m') 和 strftime('%d') 分别表示输出月份和日期,%m 和 %d 是日期格式化字符串中的占位符,zfill(2) 方法是在不足两位的数字前补一个 0,确保输出格式的一致性。因此,最终输出的每个日期都是按照 MM/DD/YYYY 的格式输出的。




7-7 字典应用--用户登录

有字典如下:
dic = {'admin':'123456','administrator':'12345678','root':'password'}
实现用户输入用户名和密码,当用户名与密码和字典中的键值对匹配时,显示“登录成功”,否则显示“登录失败”,登录失败时允许重复输入三次。

输入格式:
在两行中分别输入用户名和密码

输出格式:
"登录成功"或"登录失败"

输入样例:
admin
12345678
admin
123456
输出样例:
登录失败
登录成功



代码示例

dic = {'admin':'123456','administrator':'12345678','root':'password'}
for i in range(3):
    username = input()
    password = input()
    if dic.get(username) == password:
        print("登录成功")
        break
    else:
        print("登录失败")




代码解析:首先,我们定义了一个字典 dic,其中包含了三个键值对,键分别为 admin、administrator 和 root,值分别为对应的密码。然后我们使用 for 循环进行三次输入操作,每次输入用户名和密码,并通过 dic.get() 方法来查找对应的密码是否匹配,如果匹配则输出“登录成功”并退出循环,否则输出“登录失败”。