二分法求平方根
tips:
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:
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:
def Car(a, b, c='宝马'): # 括号里补充你的代码
# 补充你的代码
return f'这是一辆{a}年生产,型号是{b}的{c}牌汽车。'
# 以下内容不要修修改
ls = input().split() # 根据空格切分输入字符串为列表
print(Car(*ls)) # 取列表中的全部数据做参数
自幂数
tip:
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:
# 字符串切片拼接法
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'
本题采用切片拼接的方法更为合适。
完美立方数
tips:
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:
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:
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)
加密字符串
tips:
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)) # 按名字在原列表中出现的顺序排序
英汉字典
答案解析有误
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))
计算概率
描述
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))