单选题1:
答案:A
单选题2:
答案:A 注:含头不含尾的偶数。
单选题3:
答案:D 注:sorted返回集合的列表副本。
单选题4:
答案:B
单选题5:
答案:D 注:也许没学过复数,但从题中可知复数有2部分——实部与虚部,real是“实”,不可能是虚数部分。
编程题1:
代码:
·
·
N = int(input())print(N+N)
编程题2:代码:
·
·
s = input()print(s[0]+s[-1])
编程题3:代码:
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
N = int(input())nums = list(map(int, input().split(',')))K = int(input())#构建全部集合all = set()def plus(ns,rst): if len(rst) == K: all.add(sum(rst)) rst.clear() if len(ns) + len(rst) < K: return for i in range(len(ns)): ns1 = ns.copy() rst1 = rst.copy() rst1.append(ns1.pop(i)) plus(ns1,rst1)
plus(nums,[])
#合数个数hs = 0def checkPN(pn): for i in range(2,pn//2+1): if pn % i == 0: return 1 return 0for it in all: hs += checkPN(it) rst = [str(len(all)),str(hs)]
print(",".join(rst))
解说: 这主要是组合问题,附带质数与合数的概念编程。为了能使没学过组合数学知识的人能理解,本解法采用手动组合:集合中抽出一个元素与剩下的元素组合,如此类推。 Python列表的实现方法是:浅拷贝原列表list.copy(),然后list.pop(i)一个元素放入浅拷贝的结果列表中,用剩下的列表和这个浅拷贝的结果列表递归调用。核心代码如下:
·
·
·
·
·
for i in range(len(ns)): ns1 = ns.copy() rst1 = rst.copy() rst1.append(ns1.pop(i)) plus(ns1,rst1)
递归函数plus除了核心代码外,还要返回条件:当列表的元素数与已有结果数之和小于K,代码如下:
·
·
if len(ns) + len(rst) < K: return
递归函数plus还需要统计,当所选元素达到K个时,产生一个组合,计算结果,清理结果列表,进入下一个递归过程:
·
·
·
if len(rst) == K: all.add(sum(rst)) rst.clear()
采用合数的概念找出合数的个数,代码如下:
·
·
·
·
·
·
·
·
·
#合数个数hs = 0def checkPN(pn): for i in range(2,pn//2+1): if pn % i == 0: return 1 return 0for it in all: hs += checkPN(it)
编程题4:代码:
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
N = int(input())X, Y = map(int, input().split(','))#N行的杨辉三角形,用直角的杨辉三角形问题就非常明显line = [1]yh = [line]for i in range(1,N): temp = [1] for j in range(1,len(line)): temp.append(line[j]+line[j-1]) temp.append(1) yh.append(temp) line=tempxyv = yh[X-1][Y-1]ycv = 0for i in range(Y-1,N): ycv += yh[i][Y-1]
rst = str(xyv), str(ycv)
print(",".join(rst))
解说: 把杨辉三角形画成直角的,因此可以认为杨辉三角形是切去右上角的(对角线除外)的矩阵(当然也可以用0补全为矩阵),所谓的行列,就是这个矩阵的行列了。
因此,只要生成杨辉三角形的行列表,问题就解决了。本处采用循环法逐行生成,代码如下:
·
·
·
·
·
·
·
·
·
line = [1]yh = [line]for i in range(1,N): temp = [1] for j in range(1,len(line)): temp.append(line[j]+line[j-1]) temp.append(1) yh.append(temp) line=temp
X行Y列的值:
·
xyv = yh[X-1][Y-1]
Y列的和:
·
·
·
ycv = 0for i in range(Y-1,N): ycv += yh[i][Y-1]
编程题5:
代码:
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
N = int(input())nums = list(map(int,input().split()))#构建01矩阵maxHigh = max(nums)mx = []for i in range(N): mx.append([1]*nums[i]+[0]*(maxHigh-nums[i]))
minHigh = min(nums)#最大面积maxA = minHigh * N#分层统计for i in range(minHigh,maxHigh): s = 0 j = 0 while j < N: while j < N and mx[j][i] == 0: #定位到非0 j += 1 while j < N and mx[j][i] > 0: #连续块 s += 1 j += 1 if s > 0: tmp = s * (i+1) #矩形面积 if tmp > maxA: maxA = tmp s = 0 print(maxA)
解说: 从“上面有砖,下面一定有砖“的事实出发,只要从底层开始往上逐层统计就可以得到最大的矩形。 我们用一个列表表示1列砖,为了便于分层统计,用0填充与最高列长度相同:
·
·
·
·
maxHigh = max(nums)mx = []for i in range(N): mx.append([1]*nums[i]+[0]*(maxHigh-nums[i]))
用循环法按层统计,循环体内含两个循环,第一个用于定位开始的1,第二个循环用于统计连续1的个数,从而计算矩形面积。
·
·
·
·
·
·
·
·
·
·
·
·
·
·
for i in range(minHigh,maxHigh): s = 0 j = 0 while j < N: while j < N and mx[j][i] == 0: #定位到非0 j += 1 while j < N and mx[j][i] > 0: #连续块 s += 1 j += 1 if s > 0: tmp = s * (i+1) #矩形面积 if tmp > maxA: maxA = tmp s = 0
编程题6:
代码:
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
N = int(input())rooms = [set(input().split(',')) for i in range(N)]A, B = map(int, input().split(','))A, B = A-1, B-1
def checkLink(lst, tar): for r in lst: if len(r & tar) > 0: #与其中一个相连 return True return False
rA = rooms[A]rB = rooms[B]if len(rA & rB) > 0: #A,B直通 minR = 1else: minR = -1 sm = 0 #分层统计 lst1 = [rA] rooms.remove(rA) rooms.remove(rB) lst2 = rooms while len(lst1)>0 and len(lst2)>0: sm += 1 hasFound = False tmpLst1 = [] tmpLst2 = [] for r in lst2: if checkLink(lst1,r): if len(r & rB) > 0: #通B sm += 1 hasFound = True break else: tmpLst1.append(r) #压入下层 else: tmpLst2.append(r) if hasFound: minR = sm break lst1=tmpLst1 lst2=tmpLst2 #下一层
print(minR)
解说: 每个房间都可以与0个到多个房间相连,抽象出来就是“图”。那么是无向图还是有向图呢? 我们仔细想一想,对于求从A节点(房间)到B节点的最短路径,因此图中的回环是没有意义的。于是这个问题就可以转化为“有向图”求最短路径问题。本文采用有向图的分层遍历法求解。 由于多个房间可以有同一个传送门,使用集合的交集进行判定最好不过了。例如,A直通B代码:
·
·
if len(rA & rB) > 0: #A,B直通 minR = 1
有向图的分层遍历法求解:第一层是A房间,尝试A与其它房间(B除外)关联,如果有连接,检查是否与B房间相连,如果是就结束,否则加入收集器1(tmpLst1,与上一层有联系);如果无连接,加入收集2(tmpLst2,与上一层无联系)。代码:
·
·
·
·
·
·
·
·
·
if checkLink(lst1,r): if len(r & rB) > 0: #通B sm += 1 hasFound = True break else: tmpLst1.append(r) #压入下层 else: tmpLst2.append(r)
往下推层:收集器1、2分别赋值给lst1、2,进入下一轮循环:
·
·
lst1=tmpLst1 lst2=tmpLst2 #下一层
循环条件,lst1和lst2都有元素:
·
while len(lst1)>0 and len(lst2)>0: