选择题

T1. 执行以下代码,输出结果是()。

lst = "abc"print(lst+lst)
  • abcabc
  • abc
  • lst+lst
  • abc+abc

T2. 执行以下代码,输出的结果是()。

age = {16,18,17}print(type(sorted(age)))

sorted(iterable, cmp=None, key=None, reverse=False) 将返回一个新的 list,不会改变原来的可迭代对象。

T3. 导入random标准库,执行print(random.randrange(2,20,2))语句,可能输出的结果是()。

  • 2
  • 5
  • 13
  • 20

random.randrange ([start,] stop [,step])

  • 必须参数stop表示随机生成的范围上限(不包括上限
  • start表示随机生成的范围下限(包括下限
  • step表示随机生成数之间的间隔,默认是1。

T4. 下列选项哪一个是转为整数的函数()?

  • str()
  • int()
  • float
  • list()

T5. 以下关于Python中复数描述,错误的是()。

  • 复数可以看作二元有序浮点数(x,y)
  • 实部和虚部都是浮点数
  • 虚数部分的后缀可以是”j”,也可以是”J”
  • 已知复数a,可以使用real获得虚数部分。

在Python中,复数类型用complex表示。它可以通过以下方式创建:

  • 直接指定实部和虚部:complex(real, imag),real是实数部分,imag是虚数部分。
  • 使用字符串:complex(string)

例如:

a = complex(3, 4) # 创建一个复数3+4ja = complex('3+4j') # 创建一个复数3+4j

编程题

T1. N + N

问题描述

给定一个正整数 NNN,计算出 N + NN+NN+N的值。
例如: N = 4N = 4N=4 4 + 44+44+4的值为 888

输入描述

输入一个正整数 NNN

输出描述

输出 N + NN+NN+N的值

样例输入

4

样例输出

8

代码实现

n = int(input())print(n + n)

T2. 字符

问题描述

给定一个只包含小写字母的字符串 SSS SSS长度 ≥ 3≥33),请输出字符串 SSS的第一个字符和最后一个字符。例如:
S ="abc" a b cabcabc的第一个字符为 aaa,最后一个字符为 ccc,故输出 a cacac

输入描述

输入一个只包含小写字母的字符串 SSS SSS长度 ≥ 3≥33)。

输出描述

输出字符串 SSS的第一个字符和最后一个字符,两个字符之间没有空格及其他字符

样例输入

abc

样例输出

ac

代码实现

s = input()print(s[0] + s[-1])

T3. 数字币

问题描述

提示信息:合数指自然数中除了能被1和本身整除外,还能被其它正整数整除的数。例如44 444 4除了能被11 144 4整除,还可以被22 2整除。

小明收藏了 NNN 2 ≤ N ≤ 252≤N≤252N25)个数字币,每个数字币上都有一个面值(面值可以重复)。从数字币中任选 KKK 2 ≤ K ≤ N2≤K≤N2KN)个,有多种选法,请将每次选择的数字币上的面值累加,然后解决以下两个问题:

  • 问题1:累加的和中有多少种不同的结果
  • 问题2:累加的和中有多少个不同的合数

例如: N = 5N=5N=5 K = 3K=3K=3 555个数字币上的面值分别为 2 、 1 、 4 、 5 、 32、1、4、5、321453,任选 333个数字币,有 101010种选法,将每种选法上的面值累加: 2 + 1 + 4 = 7 、 2 + 1 + 5 = 8 、 2 + 1 + 3 = 6 、 2 + 4 + 5 = 11 、 2 + 4 + 3 = 9 、 2 + 5 + 3 = 10 、 1 + 4 + 5 = 10 、 1 + 4 + 3 = 8 、 1 + 5 + 3 = 9 、 4 + 5 + 3 = 122+1+4=7、2+1+5=8、2+1+3=6、2+4+5=11、2+4+3=9、2+5+3=10、1+4+5=10、1+4+3=8、1+5+3=9、4+5+3=122+1+4=72+1+5=82+1+3=62+4+5=112+4+3=92+5+3=101+4+5=101+4+3=81+5+3=94+5+3=12

其中累加的和中有 777种不同的结果,分别是 7 、 8 、 6 、 11 、 9 、 10 、 127、8、6、11、9、10、127861191012;累加的和中有 555个不同的合数,分别是 8 、 6 、 9 、 10 、 128、6、9、10、128691012

输入描述

第一行输入一个正整数 NNN 2 ≤ N ≤ 252≤N≤252N25),表示数字币的个数。
第二行输入 NNN个正整数( 1 ≤1≤1正整数 ≤ 1000≤10001000),表示数字币上的面值,正整数之间以一个英文逗号隔开。
第三行输入一个正整数 KKK 2 ≤ K ≤ N2≤K≤N2KN),表示所要选取的数字币个数。

输出描述

输出两个整数,分别表示累加的和中不同结果的个数以及累加的结果中不同合数的个数,两个整数之间以一个英文逗号隔开。

样例输入

52,1,4,5,33

样例输出

7,5

代码实现

n = int(input())a = eval(input())k = int(input())d = {}ans1, ans2 = 0, 0b = [0] * n# 检查x是否为合数def check(x):i = 2while i * i <= x:if x % i == 0:return Truei += 1return Falsedef dfs(t, last, s):if t == k:global ans1, ans2# 如果字典中不存在sif s not in d:d[s] = 1ans1 += 1# 检查是否为合数if check(s):ans2 += 1return;for i in range(last + 1, n):dfs(t + 1, i, s + a[i])dfs(0, -1, 0)print('%d,%d' % (ans1, ans2))

T4. 杨辉三角

问题描述

提示信息:杨辉三角就是一个用数排列起来的三角形(如下图),杨辉三角规则如下:

  1. 每行第一个数和最后一个数都为11 1,其它每个数等于它左上方和右上方的两数之和;
  2. nn n行有nn n个数。

注意:“列”指的是如图所标注的斜列。

小青对杨辉三角的特点和规律研究得很明白,现要考察你对杨辉三角的熟悉程度,首先告知你这是一个 NNN行的杨辉三角,然后又告知了两个数值 XXX YYY XXX表示第几行, YYY表示第几列),让你根据杨辉三角的特点和观察到的规律解决以下两个问题。

  • XX X行第YY Y列对应的数是多少;
  • 求出NN N行的杨辉三角中第YY Y列中所有数的和。

例如: N = 5N=5N=5 555行的杨辉三角如下图。

X = 5X=5X=5 Y = 3Y=3Y=3,第 555行第 333列对应的数为 666;第 333列中所有数的和为 101010 10 = 6 + 3 + 110 = 6 + 3 + 110=6+3+1)。

输入描述

第一行输入一个正整数 NNN 2 ≤ N ≤ 302≤N≤302N30),表示杨辉三角的行数
第二行输入两个正整数 XXX YYY 1 ≤ Y ≤ X ≤ N1≤Y≤X≤N1YXN),分别表示第 XXX行和第 YYY列,正整数之间以一个英文逗号隔开。

输出描述

输出两个整数,分别表示 NNN行的杨辉三角中第 XXX YYY列对应的数,及第 YYY列上所有数的和,两个整数之间以一个英文逗号隔开。

样例输入

55,3

样例输出

6,10

代码实现

n = int(input())x, y = eval(input())# 初始化二维列表f = [[0] * (n + 1) for _ in range(n + 1)]# 计算杨辉三角,行列的下标从1开始for i in range(1, n + 1):for j in range(1, i + 1):if i == 1 or j == i:f[i][j] = 1else:f[i][j] = f[i - 1][j] + f[i - 1][j - 1]ans1 = f[x][y]ans2 = 0for i in range(1, n + 1):ans2 += f[i][y];print('%d,%d' % (ans1, ans2))

T5. 涂鸦

问题描述

工人砌了一面奇特的砖墙,该墙由 NNN列砖组成( 1 ≤ N ≤ 1 06 1≤N≤10^61N106),且每列砖的数量为 Ki K_iKi 1 ≤ Ki≤ 1 04 1≤K_i≤10^41Ki104,相邻两列砖之间无缝隙),每块砖的长宽高都为 111

小蓝为了美化这面墙,需要在这面墙中找到一块面积最大的矩形用于涂鸦,那么请你帮助小蓝找出最大矩形,并输出其面积。

例如: N = 6N = 6N=6,表示这面墙有 666列,每列砖的数量依次为 3 、 2 、 1 、 5 、 6 、 23、2、1、5、6、2321562,如下图:

图中虚线部分是一块面积最大的矩形,其面积为 101010

输入描述

第一行输入一个正整数 NNN 1 ≤ N ≤ 1 06 1≤N≤10^61N106),表示这面砖墙由几列砖组成

第二行输入 NNN个正整数 Ki K_iKi 1 ≤ Ki≤ 1 04 1≤K_i≤10^41Ki104),表示每列砖的数量,正整数之间以一个空格隔开。

输出描述

输出一个正整数,表示最大矩形的面积。

样例输入

63 2 1 5 6 2

样例输出

10

算法思想1(60分,暴力枚举)

矩形的面积等于列数 ×\times×相邻列的高度最小值。因此可以暴力枚举所有相邻列的组合,计算其面积,然后打擂台求最大值即可。

时间复杂度

尝试所有相邻列的组合需要分别枚举开始列和结束列,时间复杂度为 O ( n2)O(n^2)O(n2)

代码实现
n = int(input())a = list(map(int, input().split()))ans = 0# 枚举矩形的开始列for i in range(n):# 枚举矩形的结束列for j in range(i, n):# 从i到j一共有j - i + 1列,这些列中高度的最小值为min(a[i : j + 1]ans = max(ans, (j - i + 1) * min(a[i : j + 1]))print(ans)

算法思想2(100分,枚举 + 单调栈)

矩形的面积等于每列砖的数量 ×\times× 与它左右相邻的且具有相同高度的列数。因此可以枚举每列砖的数量,第 iii列来说,不妨设其砖的数量为 ai a_iai

  • 向左找到第一个小于 a ia_i ai的位置 L iL_i Li
  • 向右找到第一个小于 a ia_i ai的位置 R iR_i Ri

此时以第 iii列砖为高度的矩形的面积 = ( Ri− Li− 1 ) × ai =(R_i – L_i-1)\times a_i=(RiLi1)×ai,那么只需要打擂台求最大值即可。

那么如何向左(向右)找到第一个小于 ai a_iai的位置呢,可以使用单调栈的思想,以 O ( 1 )O(1)O(1)的时间复杂度实现。

时间复杂度
  • 枚举每列砖的时间复杂度为O(n)O(n) O(n)
  • 单调栈向左(向右)找到第一个小于 a ia_i ai的位置的时间复杂度为O(1)O(1) O(1)

总的时间复杂度为 O ( n )O(n)O(n)

代码实现
n = int(input())a = list(map(int, input().split()))L = [0] * nR = [0] * n# 单调栈查找左侧第一个小于a[i]的位置L[i]stk = []for i in range(n):while len(stk) != 0 and a[stk[-1]] >= a[i]:stk.pop()if len(stk) == 0: # 左侧没有比a[i]小的数L[i] = -1else:L[i] = stk[-1] # 栈顶就是左侧第一个比a[i]小的位置stk.append(i)# 单调栈查找右侧第一个小于a[i]的位置R[i]stk = []for i in range(n - 1, -1, -1):while len(stk) != 0 and a[stk[-1]] >= a[i]:stk.pop()if len(stk) == 0: #右侧没有比a[i]小的数R[i] = nelse:R[i] = stk[-1] # 栈顶就是右侧第一个比a[i]小的位置stk.append(i)ans = 0for i in range(n):# (L, R)之间一共有R - L - 1列ans = max(ans, a[i] * (R[i] - L[i] - 1)) print(ans)

T6. 传送门(仅中、高级组)

问题描述

在一个神奇空间里有 NNN个房间,房间从 111 NNN编号,每个房间可能有一个或多个传送门,每个传送门都有一个编号,如果相同编号的传送门同时出现在多个房间中,表示这些房间可以互通。
给定两个房间的编号 AAA BBB,请找出从房间 AAA到达房间 BBB最少需要经过几个传送门。
例如: N = 3N=3N=3 333个房间中传送门的编号分别为:
房间 111 1 , 4 , 61,4,61,4,6
房间 222 2 , 3 , 4 , 82,3,4,82,3,4,8
房间 333 3 , 6 , 93,6,93,6,9
其中房间 111和房间 222互通,共用 444号传送门;房间 111和房间 333互通,共用 666号传送门;房间 222和房间 333互通,共用 333号传送门;当 A = 1A=1A=1 B = 2B=2B=2,从房间 111到达房间 222,共有两种路线:

  • 路线11 1:从房间11 1通过44 4号传送门进入房间22 2,共经过11 1个传送门。如下图橙色路线所示。
  • 路线22 2:从房间11 1通过66 6号传送门进入房间33 3,再从房间33 3通过33 3号传送门进入房间22 2,共经过22 2个传送门;故从房间11 1到达房间22 2最少需要经过11 1个传送门。如下图黑色路线所示。

输入描述

第一行输入一个正整数 NNN 2 ≤ N ≤ 202≤N≤202N20),表示房间数量。
接下来输入 NNN行,每行包含多个正整数( 1 ≤1≤1正整数 ≤ 100≤100100),第 222行到第 N + 1N+1N+1行依次表示 111 NNN号房间内所有传送门的编号,正整数之间以一个英文逗号隔开。
最后一行输入两个正整数 AAA BBB 1 ≤ A ≤ N , 1 ≤ B ≤ N1≤A≤N,1≤B≤N1AN1BN,且 A ≠ BA≠BA=B),表示两个房间的编号,正整数之间以一个英文逗号隔开。

输出描述

输出一个整数,表示从房间 AAA到达房间 BBB最少需要经过几个传送门,如果房间 AAA不能到达房间 BBB,则输出 − 1-11

样例输入

31,4,62,3,4,83,6,91,2

样例输出

1

算法思想

  • 首先,输入每个房间的传送门编号,可以计算出任意两个房间是否有传送门相连
  • 然后,可以通过BFS求到起点AA A的最短路径。

代码实现

n = int(input())a = []for i in range(n):b = eval(input())a.append(b)A, B = eval(input())# g数组存储两个房间是否有传送门g = [[0] * n for _ in range(n)]for i in range(n):for j in range(i + 1, n):for x in a[i]:if x in a[j]:# 第i个房间和第j个房间有传送门g[i][j] = g[j][i] = 1break# bfs求最短路ans = 0st = [0] * nq = [] # 队列q.append((A, 0)) # 将起点和到起点的距离入队st[A] = 1 # 将起点标记为已访问# 只要队列不空,bfs计算到起点的最短路径while len(q) != 0:x, d = q.pop(0)if(x == B): # 如果到达终点ans = dbreakfor i in range(n):# 如果i点已访问,或者x到i之间没有传送门if st[i] == 1 or g[x][i] == 0:continueq.append((i, d + 1))print(ans)