Python四六级考试,快来测试一下自己的编程水平吧

网友投稿 1166 2022-05-29

文章目录

1 选择题(每题2分,共20分)

2 简答题(每题3分,共30分)

3 应用题(每题5分,共50分)

3.1 庞大的牛群

3.2 古堡之门

3.3 二维列表转置

3.4 用print函数画圆

3.5 约瑟夫环

3.6 扑克牌中的顺子

3.7 青蛙上台阶

3.8 24点游戏

3.9 背包问题

3.10 空间直线相交问题

参-

1 选择题

2 简答题

3 应用题

3.1 庞大的牛群

3.2 古堡之门

3.3 二维列表转置

3.4 用print函数画圆

3.5 约瑟夫环

3.6 扑克牌中的顺子

3.7 青蛙上台阶

3.8 24点游戏

3.9 背包问题

3.10 空间直线相交问题

不要当真,这只是一套模仿英语四六考试的Python编程能力自测题,完全基于Python基础语法和标准模块,仅最后一题,用到了NumPy模块。参-附于文末,读者可自行核对。如果得分超过60分,相当于英语四级水平;得分超过80分,相当于英语六级水平。

1 选择题(每题2分,共20分)

A C是其中最早古老的

B C#是其中最年轻的

C C++比Java的历史更久

D Java比Python的历史更久

A 詹姆斯·高斯林(James Gosling)

B 林纳斯·托瓦兹(Linus Torvalds)

C 吉多·范罗苏姆(Guido van Rossum)

D 廖雪峰

A [1,2,3]

B [4,5]

C [5,3,1]

D 显示异常信息

A [1,2,9,9,5]

B [1,2,9,5]

C [1,2,[9],5]

D 显示异常信息

A d[‘name’]

B d.name

C d.get(‘name’)

D d.get(‘age’)

A a[0] = b[1]

B a[0] == b[1]

C a+b

D (*a, *b)

A list(s)

B set(s)

C tuple(s)

D dict(s)

A [i if i%2 else i*2 for i in range(5)]

B [i if i%2 for i in range(5)]

C [i for i in range(5) if i%2]

D x = 3 if 3*7==21 else 4

[True, 5, 0, False, None, '0', '', 'False'].count(False)

1

A 1

B 2

C 3

D 4

''.join(map(lambda s:s*2, 'abc'))

1

A ‘abcabc’

B [‘aa’, ‘bb’, ‘cc’]

C [‘abc’, ‘abc’]

D ‘aabbcc’

2 简答题(每题3分,共30分)

3 and 4 * 5 or 6

1

z = zip('xyz', (1,2,3)) for i in range(2): for k, v in z: print('%s=%d'%(k,v))

1

2

3

4

import threading import time def func(): for i in range(5): print(i) time.sleep(1) threading.Thread(target=func).start() time.sleep(3) print('程序结束')

1

2

3

4

5

6

7

8

9

10

11

3 应用题(每题5分,共50分)

3.1 庞大的牛群

假定你现在养了一头母牛,它每年元旦都生一头小母牛。每头小母牛从四周岁开始,每年元旦也生一头小母牛。不考虑牛的寿命和生育年限,过了n个元旦之后,你总共拥有多少头牛?

3.2 古堡之门

福尔摩斯到某古堡探险,看到门上写着一个奇怪的算式:

ABCDE × G = EDCBA

1

他对华生说:“ABCDE应该代表不同的数字,G也代表某个数字!”

华生:“我猜也是!”

于是,两人沉默了好久,还是没有算出合适的结果来。

请利用计算机的优势,找到破解的答案。

3.3 二维列表转置

严格讲,Python的列表并没有维度的概念。这里说的二维列表是指类似下面这样的列表。

[ [1, 2, 3], [4, 5, 6], [7, 8, 9] ]

1

2

3

请实现二维列表的转置(行列互换,首行变首列,尾行变尾列,如下所示)。

[ [1, 4, 7], [2, 5, 8], [3, 6, 9] ]

1

2

3

3.4 用print函数画圆

使用print()函数打印星号,形成一个近似的圆。考虑到在文本显示模式下字符的宽高不相等,以及字符水平间距和行间距不相等等因素,可以在水平方向重复字符以保持合适的看高比例。

3.5 约瑟夫环

从1开始的n个连续整数顺时针组成n个元素的环形队列,从元素1开始沿顺时针方向计数,将第m个元素剔除队列,紧接着从下一个元素重新开始计数,将第m个元素剔除队列……直至队列剩余一个元素,并返回该元素的值。

3.6 扑克牌中的顺子

从扑克牌中随机抽5张牌,判断是不是顺子,即这5张牌是不是连续的。2~10为数字本身,A为1,J为11,Q为12,K为13,大小王用0表示,可代表任意数字。

3.7 青蛙上台阶

青蛙每次至少可以跳上一层台阶,最多可以跳上两个台阶,计算青蛙跳上N层台阶总共有多少种方式。

3.8 24点游戏

几乎每个人都玩过24点游戏,规则也很简单:任意给出4个数字(视难度不同,一般是10以内或13以内的数字,允许重复),每个数字只能且必须使用1次,利用加减乘除四则运算,使得计算结果为24。例如,4个数字分别为5,5,5,1,则有(5-1/5)*5 = 24。请用代码解决24点问题,若有解,则打印解,若无解,则打印无解。

3.9 背包问题

在一款英雄对战游戏中,玩家拥有m件装备和n位英雄,他可以给每一位英雄分配0件或多件装备,而不同的英雄拥有不同数目的装备时将获得不同的攻击力。玩家如何分配这m件装备,可以使得n个英雄获得的攻击力的和最大?以玩家拥有5件装备和3位英雄为例,列表p共有3行6列,对应着3位英雄分别拥有从0到5件装备时的攻击力。

3.10 空间直线相交问题

ABCD是欧氏空间中不重合的四个点,判断过点AB的直线和过点CD的直线是否相交。

参-

1 选择题

DCCBBADBBD

2 简答题

参-1

>>> 0xab + 0b1100 183

1

2

参-2

>>> int('0xab', base=16) + int('0b1100', base=2) 183

1

2

参-

>>> ''.join([chr(ord('A')+i) for i in range(26)]) 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'

1

2

参-

>>> cmd = input('请变量名和变量值(以等号分隔):') 请变量名和变量值(以等号分隔):x=5 >>> exec(cmd) >>> x 5

1

2

3

4

5

参-

>>> s = 'erwerflkfjsfldkfberwefrasdafsasfdadfasd' >>> max(set(s), key=s.count) 'f'

1

2

3

参-

def is_isomo(n): return str(n*n)[-len(str(n)):] == str(n) >>> is_isomo(5) True

1

2

3

4

5

这段代码中两次使用str(n),效率一定会打折,追求完美的同学肯定无法接受。下面的代码使用了海象符号(Py3.8及更高版本支持),可以完美地解决这个问题。

def is_isomo(n): return str(n*n)[-len((s:=str(n))):] == s >>> is_isomo(6) True

1

2

3

4

5

参-

写成下面这样,看起来没有问题,但若存在重复元素,则可能导致结果错误。

>>> def find_lucky(arr): return list(filter(lambda x:x==arr.index(x), arr)) >>> find_lucky([1, 1, 2, 5]) [2]

1

2

3

4

5

这样写才是正确的。

>>> def find_lucky(arr): return [item[1] for item in filter(lambda x:x[0]==x[1], enumerate(arr))] >>> find_lucky([1, 1, 2, 5]) [1, 2]

1

2

3

4

5

参-

2的整数次幂,写成二进制一定是高位为1其余为0。利用这个特征,很容易判断一个数是否是2的整数次幂。

>>> def check_pow(num): return num > 0 and num & num-1 == 0 >>> check_pow(256) True

1

2

3

4

5

3 and 4 * 5 or 6

1

参-

20

1

z = zip('xyz', (1,2,3)) for i in range(2): for k, v in z: print('%s=%d'%(k,v))

1

2

3

4

参-

x=1 y=2 z=3

1

2

3

import threading import time def func(): for i in range(5): print(i) time.sleep(1) threading.Thread(target=func).start() time.sleep(3) print('程序结束')

1

2

3

4

5

6

7

8

9

10

11

参-

4

1

3 应用题

3.1 庞大的牛群

假定你现在养了一头母牛,它每年元旦都生一头小母牛。每头小母牛从四周岁开始,每年元旦也生一头小母牛。不考虑牛的寿命和生育年限,过了n个元旦之后,你总共拥有多少头牛?

参-1(5分)

从第5个元旦开始,每年新增的小牛数量是4年前的母牛总数,因此过了n个元旦之后牛的数量,等于4年前的牛的数量,加上上一个年的牛的数量。

>>> def cows(n): if n < 4: return n+1 return cows(n-1) + cows(n-4) >>> cows(5) 7 >>> cows(10) 36 >>> cows(20) 907

1

2

3

4

5

6

7

8

9

10

11

参-2(5分)

递归虽然简洁,但未必是最佳选择。本题的四级参-是一个非线性递归,复杂度为递归深度的平方,效率很低。其实,同样的思路,不用递归实现的话,速度就会快很多,只是代码没有递归那么优雅。

>>> def cows(n): if n < 4: return n+1 result = [1,2,3,4] for i in range(4, n+1): result.append(result[0]+result[-1]) result = result[1:] return result[-1] >>> cows(5) 7 >>> cows(10) 36 >>> cows(20) 907

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

3.2 古堡之门

福尔摩斯到某古堡探险,看到门上写着一个奇怪的算式:

ABCDE × G = EDCBA

1

他对华生说:“ABCDE应该代表不同的数字,G也代表某个数字!”

华生:“我猜也是!”

于是,两人沉默了好久,还是没有算出合适的结果来。

请利用计算机的优势,找到破解的答案。

参-1(3分)

中规中矩的写法,代码结构存在改进空间。

>>> def cbble(): for i in range(10000, 100000): a, quotient = divmod(i, 10000) b, quotient = divmod(quotient, 1000) c, quotient = divmod(quotient, 100) d, e = divmod(quotient, 10) parts =set([a,b,c,d,e]) if len(parts) == 5: for j in range(1, 10): k = 10000*e + 1000*d + 100*c + 10*b +a if j not in parts and i*j == k: print('%d x %d = %d'%(i, j, k)) break >>> cbble() 21978 x 4 = 87912

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

参-2(5分)

追求结构的优美甚于追求更高的效率,尽管不是最佳选择,但对于此问题却是合适的。

>>> def cbble(): for i in range(10000, 100000): a,b,c,d,e = map(int, str(i)) parts =set([a,b,c,d,e]) if len(parts) == 5: k = 10000*e + 1000*d + 100*c + 10*b +a for j in range(1, 10): if j not in parts and i*j == k: return('%d x %d = %d'%(i, j, k)) return '此题无解!' >>> cbble() '21978 x 4 = 87912'

1

2

3

4

5

6

7

8

9

10

11

12

13

3.3 二维列表转置

严格讲,Python的列表并没有维度的概念。这里说的二维列表是指类似下面这样的列表。

[ [1, 2, 3], [4, 5, 6], [7, 8, 9] ]

1

2

3

请实现二维列表的转置(行列互换,首行变首列,尾行变尾列,如下所示)。

[ [1, 4, 7], [2, 5, 8], [3, 6, 9] ]

1

2

3

参-1(3分)

不考虑检查列表是否满足转置的条件(列表每个元素都是长度相等的列表),初级程序员根据第一直觉写出来的代码几乎都是这样的。

>>> def transpose(arr): result = list() for j in range(len(arr[0])): result.append(list()) for i in range(len(arr)): result[j].append(arr[i][j]) return result >>> transpose([[1,2,3], [4,5,6], [7,8,9]]) [[1, 4, 7], [2, 5, 8], [3, 6, 9]]

1

2

3

4

5

6

7

8

9

10

参-2(5分)

作为中高级程序员必然掌握使用一颗星(*)和两颗星(**)的魔法,内置函数用起来更是得心应手。

>>> def transpose(arr): return list(zip(*arr)) >>> transpose([[1,2,3], [4,5,6], [7,8,9]]) [(1, 4, 7), (2, 5, 8), (3, 6, 9)]

1

2

3

4

5

3.4 用print函数画圆

使用print()函数打印星号,形成一个近似的圆。考虑到在文本显示模式下字符的宽高不相等,以及字符水平间距和行间距不相等等因素,可以在水平方向重复字符以保持合适的看高比例。

参-(5分)

优秀的程序员数学至少要及格才行。画圆,得先计算出圆上个点的位置。通常要借助于参数方程,比如,令角度变量theta从0°变到360°,对应每个theta,圆上点坐标为:

x = R * cos(theta) y = R * sin(theta)

1

2

理解了这个思路,下面的代码就很容易看懂了。三角函数来自Python的标准模块math,该模块还包括度和弧度互转等很多数学函数。代码中的

>>> import math >>> def print_circle(r, k): # r为半径,k为宽高比矫正系数 theta = range(0,360,5) x = [round(r*math.cos(math.radians(i))+r) for i in theta] y = [round(r*math.sin(math.radians(i))+r) for i in theta] dots = set(zip(x,y)) for i in range(2*r+1): for j in range(2*r+1): if (i,j) in dots: print('*'*k, sep='', end='') else: print(' '*k, sep='', end='') print() >>> print_circle(5, 3) *************** ****** ****** *** *** *** ****** *** *** *** *** *** *** *** *** *** *** ****** ****** ***************

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

3.5 约瑟夫环

从1开始的n个连续整数顺时针组成n个元素的环形队列,从元素1开始沿顺时针方向计数,将第m个元素剔除队列,紧接着从下一个元素重新开始计数,将第m个元素剔除队列……直至队列剩余一个元素,并返回该元素的值。

参-(5分)

>>> def joseph(n, m): queue, start = list(range(1, n+1)), 0 while len(queue) > 1: start = (m+start-1)%len(queue) queue.pop(start) return queue[0]

1

2

3

4

5

6

3.6 扑克牌中的顺子

从扑克牌中随机抽5张牌,判断是不是顺子,即这5张牌是不是连续的。2~10为数字本身,A为1,J为11,Q为12,K为13,大小王用0表示,可代表任意数字。

参-(5分)

本题有两个环节:

从扑克牌中随机抽5张牌

随机取牌,可以使用Python的内置模块random中的sample()方法,该方法可以随机地从指定列表中提取出多个不同的元素。

判断是不是顺子

将5张牌换成对应数字,剔除0后排序。若是顺子的话,前后元素之差均为1。若不是1,同时超过1的总和大于0的个数,则不是顺子,否则为顺子。

>>> import random >>> import numpy as np >>> def get_five(): poker = list(range(1,14))*4 + [0,0] # 生成54张扑克牌 return random.sample(poker, 5) >>> def is_straight(five): no_zero = list(filter(lambda x:x>0, five)) # 剔除0 if len(no_zero) > len(set(no_zero)): # 如有重复 return False # 则不是顺子 no_zero.sort() # 非零元素排序 no_zero = np.array(no_zero) # 转为numpy数组 diff = np.diff(no_zero) # diff为相邻元素的差组成的数组 if np.sum(diff - 1) > 5-no_zero.size: # 若diff各元素减1后的和大于0的个数 return False # 则不是顺子 else: return True >>> def test(n): # 测试函数 for i in range(n): five = get_five() if is_straight(five): print(five) >>> test(100) # 测试100次 [12, 10, 11, 0, 8] [5, 1, 0, 3, 2] [10, 6, 0, 7, 9]

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

3.7 青蛙上台阶

青蛙每次至少可以跳上一层台阶,最多可以跳上两个台阶,计算青蛙跳上N层台阶总共有多少种方式。

参-1(5分)

跳一层只有一种方法,跳两层则有两种方法。要跳到K层,可以先跳到K-1层后再跳一次迈上一层,也可以先跳到K-2层后再一步跳上两层。显然,跳到K层的方法数量等于跳到K-1层的方法数量加上跳到K-2层的方法数量。基于这个推理,很容易写出递归代码。

>>> def climb(n): if n == 1: return 1 elif n == 2: return 2 else: return climb(n-1) + climb(n-2) >>> climb(10) 89

1

2

3

4

5

6

7

8

9

10

11

参-2(5分)

递归方法虽然简洁,但会受递归深度限制,无法计算超过递归深度的数值。其实,不使用递归,代码写起来也很简答。

>>> def climb(n): if n == 1: return 1 elif n == 2: return 2 c1, c2 = 1, 2 for i in range(2,n): c1, c2 = c2, c1+c2 return c2 >>> climb(10) 89

1

2

3

4

5

6

7

8

9

10

11

12

3.8 24点游戏

几乎每个人都玩过24点游戏,规则也很简单:任意给出4个数字(视难度不同,一般是10以内或13以内的数字,允许重复),每个数字只能且必须使用1次,利用加减乘除四则运算,使得计算结果为24。例如,4个数字分别为5,5,5,1,则有(5-1/5)*5 = 24。请用代码解决24点问题,若有解,则打印解,若无解,则打印无解。

参-(5分)

不考虑计算顺序的话,4个数字使用4种运算符连接的话,共有443424=1536种组合。若考虑使用括号改变计算顺序,则前述每一种组合又可分为11种情况。遍历全部153611=16896种组合,即可解决问题。另外,书写代码时如果使用内置的排列函数(permutations)和笛卡尔积函数(product),会使代码更简练。

>>> from itertools import permutations, product >>> def game24(n1,n2,n3,n4): for a,b,c,d in permutations((n1,n2,n3,n4),4): for o1,o2,o3 in product(['+','-','*','/'], repeat=3): # 笛卡尔积的另一种写法 cases = list() cases.append('%d%s%d%s%d%s%d'%(a,o1,b,o2,c,o3,d)) cases.append('(%d%s%d)%s%d%s%d'%(a,o1,b,o2,c,o3,d)) cases.append('%d%s%d%s(%d%s%d)'%(a,o1,b,o2,c,o3,d)) cases.append('%d%s(%d%s%d)%s%d'%(a,o1,b,o2,c,o3,d)) cases.append('(%d%s%d)%s(%d%s%d)'%(a,o1,b,o2,c,o3,d)) cases.append('(%d%s%d%s%d)%s%d'%(a,o1,b,o2,c,o3,d)) cases.append('((%d%s%d)%s%d)%s%d'%(a,o1,b,o2,c,o3,d)) cases.append('(%d%s(%d%s%d))%s%d'%(a,o1,b,o2,c,o3,d)) cases.append('%d%s(%d%s%d%s%d)'%(a,o1,b,o2,c,o3,d)) cases.append('%d%s((%d%s%d)%s%d)'%(a,o1,b,o2,c,o3,d)) cases.append('%d%s(%d%s(%d%s%d))'%(a,o1,b,o2,c,o3,d)) for expression in cases: try: # 捕获表达式中分母为0的异常 if eval(expression) == 24: print('答案:%s = 24'%expression) return except: pass print('无解!') >>> game24(5,5,5,1) 答案:5*(5-1/5) = 24 >>> game24(1,3,4,6) 答案:6/(1-3/4) = 24 >>> game24(10,10,4,4) 答案:(10*10-4)/4 = 24 >>> game24(7,7,3,3) 答案:7*(3/7+3) = 24 >>> game24(1,5,7,10) 答案:(1+7/5)*10 = 24 >>> game24(15,25,37,80) 无解!

1

2

3

4

5

6

7

8

9

10

11

Python四六级考试,快来测试一下自己的编程水平吧

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

3.9 背包问题

在一款英雄对战游戏中,玩家拥有m件装备和n位英雄,他可以给每一位英雄分配0件或多件装备,而不同的英雄拥有不同数目的装备时将获得不同的攻击力。玩家如何分配这m件装备,可以使得n个英雄获得的攻击力的和最大?以玩家拥有5件装备和3位英雄为例,列表p共有3行6列,对应着3位英雄分别拥有从0到5件装备时的攻击力。

p = [ [0, 1, 3, 5, 7, 9], [0, 1, 1, 3, 3, 7], [0, 3, 4, 5, 6, 7] ]

1

2

3

4

5

参-(5分)

这是一个背包问题的变形。即便不熟悉背包问题,也不难找到解题思路:

找出所有可能的装备分配方案

计算每一个方案的攻击值

选择攻击值最大的分配方案

找出将m件装备分配给n位英雄的所有方案是解决问题的核心。

>>> def bag(m, n, result, series=list()): if n == 1: for i in range(m+1): result.append(series+[i]) #print(result[-1]) else: for i in range(m+1): bag(m-i, n-1, result, series+[i]) >>> result = list() >>> bag(5, 3, result) # 将5件装备分配给3位英雄,共有56种分配方案 >>> p = [ [0,1,3,5,7,9], [0,1,1,3,3,7], [0,3,4,5,6,7] ] >>> v = list() >>> for item in result: # 计算每一种方案的攻击值 v.append(p[0][item[0]] + p[1][item[1]] + p[2][item[2]]) >>> max(v) # 最大攻击值是10 10 >>> result[v.index(max(v))] # 最佳分配方案 [4, 0, 1] # 第1位英雄持有4件装备,第2位英雄没有装备,第3位英雄持有1件装备。

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

3.10 空间直线相交问题

ABCD是欧氏空间中不重合的四个点,判断过点AB的直线和过点CD的直线是否相交。

参-(5分)

假如使用空间解析几何的方式,这个问题对于程序员来说是一个难题。不过,如果你熟悉NumPy,理解点积(np.dot)和叉积(np.cross)的话,解决这个问题就变得非常容易了。

计算向量ab和向量cd的叉积,得到一个新的向量orth

若向量orth的元素全部为零,则两直线平行,否则向量orth必定同时垂直于向量ab和向量cd

直线相交,则向量ac和向量orth的点积为零,否则直线必定不相交

>>> import numpy as np >>> def is_orthogonal(a, b, c, d): ab = np.array(a) - np.array(b) cd = np.array(c) - np.array(d) ac = np.array(a) - np.array(c) orth = np.cross(ab,cd) return orth.any() and np.dot(orth, ac) == 0 >>> a,b,c,d = (0,0,0),(1,0,0),(0,0,0),(0,1,0) >>> is_orthogonal(a, b, c, d) True >>> a,b,c,d = (0,0,0),(1,0,0),(0,0,1),(0,1,1) >>> is_orthogonal(a, b, c, d) False

1

2

3

4

5

6

7

8

9

10

11

12

13

14

HTTP Python

版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:一文入门ETCD
下一篇:C语言学习,这一篇就够了!(一)
相关文章