python123习题集

python123习题集

    • 06函数
    • 07集合
    • 08列表元组
    • 09集合
    • 10字典
    • 12随机数

06函数


二分法求平方根
tips:

  1. 二分法求解思路
  2. 精度控制
import math

n, delta = map(eval, input().split(','))
def sqrt_binary(n, delta):
    a, b = 0, n+0.25# 初始化区间
    while True:
        x = (a+b)/2
        if abs(x**2 - n) < delta:# 精度足够
            print('{:.8f}'.format(x))
            break
        elif x**2 - n < 0:# 不够大,更新下界
            a = x
        else:# 太大了,更新上界
            b = x

sqrt_binary(n, delta)
print('{:.8f}'.format(math.sqrt(n)))

汉诺塔

def hanota(n,a,b,c):
    if n == 1:
        print('{} --> {}'.format(a, c))
    else:
        hanota(n-1, a, c, b)
        print('{} --> {}'.format(a, c))
        hanota(n-1, b, a, c)
if __name__ == '__main__':
    n = eval(input())
    a,b,c = input().split()
    hanota(n, a, b, c)

特殊的数字

描述‪‬‪‬‪‬‪‬‪‬‮‬‪‬‭‬‪‬‪‬‪‬‪‬‪‬‮‬‫‬‮‬‪‬‪‬‪‬‪‬‪‬‮‬‭‬‪‬‪‬‪‬‪‬‪‬‪‬‮‬‫‬‭‬‪‬‪‬‪‬‪‬‪‬‮‬‫‬‪‬‪‬‪‬‪‬‪‬‪‬‮‬‭‬‪‬

1179 能用 3 种方法表示为 3 个不同素数平方和的整数。‪‬‪‬‪‬‪‬‪‬‮‬‪‬‭‬‪‬‪‬‪‬‪‬‪‬‮‬‫‬‮‬‪‬‪‬‪‬‪‬‪‬‮‬‭‬‪‬‪‬‪‬‪‬‪‬‪‬‮‬‫‬‭‬‪‬‪‬‪‬‪‬‪‬‮‬‫‬‪‬‪‬‪‬‪‬‪‬‪‬‮‬‭‬‪‬

如:‪‬‪‬‪‬‪‬‪‬‮‬‪‬‭‬‪‬‪‬‪‬‪‬‪‬‮‬‫‬‮‬‪‬‪‬‪‬‪‬‪‬‮‬‭‬‪‬‪‬‪‬‪‬‪‬‪‬‮‬‫‬‭‬‪‬‪‬‪‬‪‬‪‬‮‬‫‬‪‬‪‬‪‬‪‬‪‬‪‬‮‬‭‬‪‬

1179 = 1717 + 1919 + 23*23‪‬‪‬‪‬‪‬‪‬‮‬‪‬‭‬‪‬‪‬‪‬‪‬‪‬‮‬‫‬‮‬‪‬‪‬‪‬‪‬‪‬‮‬‭‬‪‬‪‬‪‬‪‬‪‬‪‬‮‬‫‬‭‬‪‬‪‬‪‬‪‬‪‬‮‬‫‬‪‬‪‬‪‬‪‬‪‬‪‬‮‬‭‬‪‬

1179 = 77 + 1313 + 31*31‪‬‪‬‪‬‪‬‪‬‮‬‪‬‭‬‪‬‪‬‪‬‪‬‪‬‮‬‫‬‮‬‪‬‪‬‪‬‪‬‪‬‮‬‭‬‪‬‪‬‪‬‪‬‪‬‪‬‮‬‫‬‭‬‪‬‪‬‪‬‪‬‪‬‮‬‫‬‪‬‪‬‪‬‪‬‪‬‪‬‮‬‭‬‪‬

1179 = 77 + 1717 + 29*29‪‬‪‬‪‬‪‬‪‬‮‬‪‬‭‬‪‬‪‬‪‬‪‬‪‬‮‬‫‬‮‬‪‬‪‬‪‬‪‬‪‬‮‬‭‬‪‬‪‬‪‬‪‬‪‬‪‬‮‬‫‬‭‬‪‬‪‬‪‬‪‬‪‬‮‬‫‬‪‬‪‬‪‬‪‬‪‬‪‬‮‬‭‬‪‬

请输出能用 6 种方式表示为 3 个不同素数平方和的最小整数。‪‬‪‬‪‬‪‬‪‬‮‬‪‬‭‬‪‬‪‬‪‬‪‬‪‬‮‬‫‬‮‬‪‬‪‬‪‬‪‬‪‬‮‬‭‬‪‬‪‬‪‬‪‬‪‬‪‬‮‬‫‬‭‬‪‬‪‬‪‬‪‬‪‬‮‬‫‬‪‬‪‬‪‬‪‬‪‬‪‬‮‬‭‬‪‬

(本题涉及的最大素数不超过100)

def prime(n):
	'''高效创建素数集列表'''
    flag = [1]*(n+2)
    p=2
    ls = []
    while(p<=n):
        ls.append(p)
        for i in range(2*p,n+1,p):
            flag[i] = 0
        while 1:
            p += 1
            if(flag[p]==1):
                break
    return ls

import itertools
ls = prime(100)
ls_2 = [s**2 for s in ls]
mul = []
for item in itertools.combinations(ls_2, 3):
    mul.append(sum(item))
mul.sort() #需要排一下序,题目要求是输出最小整数
for i in mul:
    if mul.count(i) == 6:
        print(i)
        break

参考答案,两个点效率不高,一个是素数集的创建,一个是最后查找最小整数,但是函数式编程的思想值得学习。

from itertools import combinations


def is_prime(n):
    """判断素数的函数,接收一个正整数为参数,参数是素数时返回True,否则返回False
    减小判定区间,减少循环次数,提升效率"""
    if n < 2:
        return False  # 0、1、负数以及偶数都不是素数
    for i in range(2, int(n ** 0.5) + 1):
        if n % i == 0:  # 能被2到其n-1之间的数整除的数不是素数
            return False
    else:
        return True  # for循环正常结束,未遇到return的数是素数


def combine(ls_of_prime, n):
    """根据n获得列表中的所有可能组合(3个元素为一组)"""
    comb_of_prime = []
    for c in combinations(ls_of_prime, n):
        comb_of_prime.append(c)
    return comb_of_prime


def six_ways(comb_of_prime):
    """传入所有三个素数的组合列表,计算每个组合中的元素的平方和,产生新的列表,
    遍历10000以下的整数,如果这个整数在列表中出现的次数为6次,那么便是最小的、
    可以有6 种表示方法表示为3个素数平方和的那个数"""
    result = [sum((c[0] ** 2, c[1] ** 2, c[2] ** 2)) for c in comb_of_prime]
    for i in range(10000):
        if result.count(i) == 6:   # 统计当前数字在列表中出现的次数
            return i

if __name__ == '__main__':
    lsOfPrime = [i for i in range(100) if is_prime(i)]
    combOfPrime = combine(lsOfPrime, 3)
    print(six_ways(combOfPrime))

素数求和
描述

输入一个正整数n,统计从[0,n]之间的最大的10个素数之和。本题保证测试用例至少有10个满足条件的素数。‪‬‪‬‪‬‪‬‪‬‮‬‪‬‭‬‪‬‪‬‪‬‪‬‪‬‮‬‫‬‮‬‪‬‪‬‪‬‪‬‪‬‮‬‭‬‪‬‪‬‪‬‪‬‪‬‪‬‮‬‫‬‭‬‪‬‪‬‪‬‪‬‪‬‮‬‫‬‪‬‪‬‪‬‪‬‪‬‪‬‮‬‭‬‪‬

例如:输入31 ,应求得3,5,7,11,13,17,19,23,29,31之和。

一个测试点运行错误。莫名其妙哦?

def prime(n):
    flag = [1]*(n+2)
    p = 2
    ls = []
    while p <= n:
        ls.append(p)
        for i in range(2*p, n+1, p):
            flag[i] = 0
        while 1:
            p += 1
            if flag[p] == 1:
                break
    return ls

n = eval(input())
print(sum(prime(n)[-10:]))

字符串移位
描述

在两行中分别输入一个字符串s和整数n,定义一个函数将字符串s循环向右移动n位,n为负数时左移。‪‬‪‬‪‬‪‬‪‬‮‬‪‬‭‬‪‬‪‬‪‬‪‬‪‬‮‬‫‬‮‬‪‬‪‬‪‬‪‬‪‬‮‬‭‬‪‬‪‬‪‬‪‬‪‬‪‬‮‬‫‬‭‬‪‬‪‬‪‬‪‬‪‬‮‬‫‬‪‬‪‬‪‬‪‬‪‬‪‬‮‬‭‬‪‬

若s为空串’‘,则不论n为多少,均输出’‘‪‬‪‬‪‬‪‬‪‬‮‬‪‬‭‬‪‬‪‬‪‬‪‬‪‬‮‬‫‬‮‬‪‬‪‬‪‬‪‬‪‬‮‬‭‬‪‬‪‬‪‬‪‬‪‬‪‬‮‬‫‬‭‬‪‬‪‬‪‬‪‬‪‬‮‬‫‬‪‬‪‬‪‬‪‬‪‬‪‬‮‬‭‬‪‬

如 s=‘123456’ n=3‪‬‪‬‪‬‪‬‪‬‮‬‪‬‭‬‪‬‪‬‪‬‪‬‪‬‮‬‫‬‮‬‪‬‪‬‪‬‪‬‪‬‮‬‭‬‪‬‪‬‪‬‪‬‪‬‪‬‮‬‫‬‭‬‪‬‪‬‪‬‪‬‪‬‮‬‫‬‪‬‪‬‪‬‪‬‪‬‪‬‮‬‭‬‪‬

输出结果:456123

tip:

  1. 可以联想到循环队列结构
def f(s,n):
    p=''
    if s=='':
        return p
    t=(len(s)-n)%len(s)
    p=s[t:]
    p+=s[:t]   
    return p

s=input()
n=int(input())
print(f(s,n))

汽车迷
描述

小明是一个汽车迷,看到什么汽车马上就可以说出汽车的生产年份、型号和品牌。定义一个函数,可以输出汽车的介绍。‪‬‪‬‪‬‪‬‪‬‮‬‪‬‭‬‪‬‪‬‪‬‪‬‪‬‮‬‫‬‮‬‪‬‪‬‪‬‪‬‪‬‮‬‭‬‪‬‪‬‪‬‪‬‪‬‪‬‮‬‫‬‭‬‪‬‪‬‪‬‪‬‪‬‮‬‫‬‪‬‪‬‪‬‪‬‪‬‪‬‮‬‭‬‪‬

例如输入:‪‬‪‬‪‬‪‬‪‬‮‬‪‬‭‬‪‬‪‬‪‬‪‬‪‬‮‬‫‬‮‬‪‬‪‬‪‬‪‬‪‬‮‬‭‬‪‬‪‬‪‬‪‬‪‬‪‬‮‬‫‬‭‬‪‬‪‬‪‬‪‬‪‬‮‬‫‬‪‬‪‬‪‬‪‬‪‬‪‬‮‬‭‬‪‬

2020 AMG_S65 奔驰‪‬‪‬‪‬‪‬‪‬‮‬‪‬‭‬‪‬‪‬‪‬‪‬‪‬‮‬‫‬‮‬‪‬‪‬‪‬‪‬‪‬‮‬‭‬‪‬‪‬‪‬‪‬‪‬‪‬‮‬‫‬‭‬‪‬‪‬‪‬‪‬‪‬‮‬‫‬‪‬‪‬‪‬‪‬‪‬‪‬‮‬‭‬‪‬

可以输出:‪‬‪‬‪‬‪‬‪‬‮‬‪‬‭‬‪‬‪‬‪‬‪‬‪‬‮‬‫‬‮‬‪‬‪‬‪‬‪‬‪‬‮‬‭‬‪‬‪‬‪‬‪‬‪‬‪‬‮‬‫‬‭‬‪‬‪‬‪‬‪‬‪‬‮‬‫‬‪‬‪‬‪‬‪‬‪‬‪‬‮‬‭‬‪‬

这是一辆2020年生产,型号是AMG_S65的奔驰牌汽车‪‬‪‬‪‬‪‬‪‬‮‬‪‬‭‬‪‬‪‬‪‬‪‬‪‬‮‬‫‬‮‬‪‬‪‬‪‬‪‬‪‬‮‬‭‬‪‬‪‬‪‬‪‬‪‬‪‬‮‬‫‬‭‬‪‬‪‬‪‬‪‬‪‬‮‬‫‬‪‬‪‬‪‬‪‬‪‬‪‬‮‬‭‬‪‬

要求函数具有以下功能:当用户只输入生产年份、型号时,品牌按“宝马”输出。

tip:

  1. 函数关键字传参
def Car(a, b, c='宝马'): # 括号里补充你的代码
	# 补充你的代码
    return f'这是一辆{a}年生产,型号是{b}的{c}牌汽车。'
# 以下内容不要修修改
ls = input().split()  # 根据空格切分输入字符串为列表
print(Car(*ls))       # 取列表中的全部数据做参数

07集合


自幂数
tip:

  1. 提前建立数值列表的方法多次出现了,引起重视
n = eval(input())
nums = '0123456789'
ls = [x**n for x in range(10)]# 一次性建立数值列表减少计算量
for num in range(10**(n-1), 10**n):
    total = 0 
    for s in str(num):
        total += ls[int(s)]
    if num == total:
        print(num)

手机号替换
tip:

  1. 字符串替换方法repalce(old, new, max)的第三个参数有时不可省略,因为如若不指定,解释器会从头查找子串,第三个参数max规定替换的子串数量上限
# 字符串切片拼接法
s = input()
print(s[0:3] + '****' + s[7:11])
print(s[:3] + '****' + s[7:])


# 字符串替换方法
s = input()    # 13988776777
print(s.replace(s[3:7], '****',1))  # 139****6777
s_new = s.replace(s[3:7],'****',1)  # 4-7位上的字符替换为“****”,只替换一次
print(s_new)                        # 139****6777

# 可以直接将str.replace()函数 作为print()的参数直接输出其返回值
print(s.replace(s[3:7],'****',1))   # 返回值是替换后的字符串,139****6777
print(s)
# 第三个参数 max不可省略,否则某些数据会替换异常
print(s.replace(s[3:7],'****'))# 例如输入 13413413413,替换后的字符串,****34****3
# s[3:7]的值是'1341',解释器会从头开始查找子串'1341'并替换
# 例如输入 13912341234,替换后的字符串,139********
# s[3:7]的值是'1234',解释器会从头开始查找子串'1234'并替换

此题的参考答案并不严谨,即使指定max参数,仍可能替换错误,因为解释器从头开始匹配子串。

>>> s = '13413413413'
>>> s.replace(s[3:7], '****',1)
'****3413413'

本题采用切片拼接的方法更为合适。

08列表元组


完美立方数
tips:

  1. 构造列表数组减少计算量
  2. 如果range的关键字大小逆序,并不会报错,而是直接跳过(遍历空数组,python特性)
N =  int(input())
ls = []
for i in range(1,N + 1): #计算一次i的三次方存于列表,可减少计算量
    ls.append(i * i * i) 
for a in range(2,N + 1):  #a从2-N
#for a in range(6,N + 1):  #小于6无满足条件的数,可减少计算量
    for b in range(2,a):  #b,c,d都不会大于a,这样可减少计算量
        for c in range(b,a):  #c大于等于b
            for d in range(c,a):  #d大于等于c,此设置保证非降序
                if ls[a-1] == ls[b-1] + ls[c-1] + ls[d-1]:
                #if a * a * a == b * b * b + c * c * c + d * d * d :
                    print("Cube = {},Triple = ({},{},{})".format(a,b,c,d))

奇数阶幻方
tip:

  1. 更新下标
def ODD(n):
    ls = [[0 for i in range(n)] for i in range(n)]
    x, y = 0, n//2
    for num in range(1, n**2 + 1):
        ls[x][y] = num 
        xa, ya = x-1, y+1
        if xa < 0:
            xa = n-1
        if ya > n-1:
            ya = 0
        if ls[xa][ya] != 0:
            x = x+1
            if x > n-1:
                x = 0
        else:
            x, y = xa, ya
    return ls 

n = eval(input())
result = ODD(n)
for row in result:
    print(row)

约瑟夫环问题
据说著名历史学家 Josephus有过以下的故事:Josephus及他的朋友共41人围成一个圆圈,由第1个人开始报数,每数到3该人就必须出去,然后再由下一个人重新报数,直到圆圈上少于3人为止。Josephus 将朋友与自己安排在第16个与第31个位置,成为最后剩下的人。‪‬‪‬‪‬‪‬‪‬‮‬‪‬‭‬‪‬‪‬‪‬‪‬‪‬‮‬‫‬‮‬‪‬‪‬‪‬‪‬‪‬‮‬‭‬‪‬‪‬‪‬‪‬‪‬‪‬‮‬‫‬‭‬‪‬‪‬‪‬‪‬‪‬‮‬‫‬‪‬‪‬‪‬‪‬‪‬‪‬‮‬‭‬‪‬

扩展这个问题,当人数为n,每次报数为k时,求解最后的K-1个剩下的人的位置
tip:

  1. 这是一个经典问题
n, k = map(int, input().split())
ls = list(range(1,n+1))
while len(ls) > k-1:
    ls = ls[k:] + ls[:k-1]# 核心
print('Data Error!') if (k < 2 or n < k) else print(ls)

09集合


加密字符串

tips:

  1. 去重后的排序关键字,依据可以是字符串也可以是列表字符串,可以混搭
  2. 获取未出现过的元素,可用集合减法
  3. 字符串构建映射字典来完成元素替换
import string

uppercase = string.ascii_uppercase
s = input().upper()# 原始单词
word = list(set(s))# 单词去重
word.sort(key = s.index)# 去重后按原始单词排序
code = list(set(uppercase)-set(word))# 利用集合运算清除单词中出现的重复字母
code.sort()
keys = ''.join(word+code)# 合并构成密钥
d = str.maketrans(uppercase, keys)# 利用字符串方法创建映射字典,一一对应
decode = input().upper()
print(decode.translate(d))# 通过映射字典解码

列表去重

name_lst = input().split(',')                         # 输入的字符串节分为列表
name_no_duplicate = list(set(name_lst))               # 去除重复的元素
print(sorted(name_no_duplicate, key=name_lst.index))  # 按名字在原列表中出现的顺序排序

10字典


英汉字典
答案解析有误

import string
d = {}
with open('dicts.txt', 'r', encoding = 'utf-8') as f:
    for line in f:
        line = line.strip().split()
        d.update(dict({line[0]:line[1:]}))# 在这里,遗漏了词的译文
ls = input().lower()
ls = ls.replace("'s",' is')
ls = ls.replace("n't",' not')
for x in string.punctuation:
    ls = ls.replace(x, ' ')
ls = ls.split()
for s in ls:
    if not d.get(s):
        print(s,'自己猜')
    else:
        print(s, *d.get(s))

12随机数


计算概率

描述

A和B两个赌徒各有一百块钱,他们通过抛硬币来赌,正面朝上A赢,B要给A十块钱,反面朝上B赢,A要给B二十块钱,一直持续其中一个人把钱输光为止。请用随机数计算A和B最后把钱输光的概率各是多少?(结果用百分数表示,保留2位小数)‪‬‪‬‪‬‪‬‪‬‮‬‪‬‭‬‪‬‪‬‪‬‪‬‪‬‮‬‫‬‮‬‪‬‪‬‪‬‪‬‪‬‮‬‭‬‪‬‪‬‪‬‪‬‪‬‪‬‮‬‫‬‭‬‪‬‪‬‪‬‪‬‪‬‮‬‫‬‪‬‪‬‪‬‪‬‪‬‪‬‮‬‭‬‪‬

tip:
函数式编程能够提升程序效率(这题不采用函数式编程最后一个测试点过不了)

import random

sd, n = map(int, input().split(','))
random.seed(sd)
cnt = 0
for i in range(n):
    a, b = 100, 100
    while a > 0 and b > 0:
        while a > 0 and b > 0:
            num = random.randint(0,1)
            if num == 0:
                b -= 10
                a += 10
            else:
                a -= 20
                b += 20
        else:
            if a <= 0:
                cnt += 1
print('A输光的概率为:{:.2%}'.format(cnt/n))
print('B输光的概率为:{:.2%}'.format(1-cnt/n))

vs

import random

def win():
    a, b = 100, 100
    while a > 0 and b > 0:
        num = random.randint(0,1)
        if num == 0:
            b -= 10
            a += 10
        else:
            a -= 20
            b += 20
    else:
        if a <= 0:
            return 1 
        return 0

sd, n = map(int, input().split(','))
random.seed(sd)
cnt = 0
for i in range(n):
    if win():
        cnt += 1
print('A输光的概率为:{:.2%}'.format(cnt/n))
print('B输光的概率为:{:.2%}'.format(1-cnt/n))

你可能感兴趣的:(#,python基础练习)