1. 哥德巴赫猜想
问题描述:
2000
以内的不小于4
的正偶数都能够分解为两个素数之和(即验证歌德巴赫猜想对2000以内的正偶数成立)。
问题分析:
根据问题描述,为了验证歌德巴赫猜想对2000以内的正偶数都是成立的,要将整数分解为两部分,然后判断分解出的两个整数是否均为素数。若是,则满足题意,否则应重新进行分解和判断。
import math
# 判断是否为素数
def fun(n):
if n == 2:
return 1 # n是2,返回1
if n % 2 == 0:
return 0 # n是偶数,不是素数,返回0
i = 3
while i <= math.sqrt(n):
if n % i == 0:
return 0 # n是奇数,不是素数,返回0
i += 2
return 1 # n是除2以外的素数,返回1
# 验证哥德巴赫猜想
def guess(n):
ok = 0 # 进入循环前先置标志位
i = 2
while i <= (n // 2):
if fun(i):
if fun(n - i):
print("%d %d\n" % (i, n - i)) # i和n-i都是素数,则打印
ok = 1
if i != 2:
i += 1
if ok == 1:
break # 已打印出所需要的输出结果,跳出循环
i += 1
if __name__ == "__main__":
while True: # 循环输入
n = int(input())
guess(n) # 调用函数验证哥德巴赫猜想
2.可逆素数
问题描述:
请从小到大输出所有4位数的可逆素数。可逆素数是指一个素数将其各位数字的顺序倒过来构成的反序数也是素数。
问题分析:
题目的难点已经不在于判断一个数是否为素数,而在于如何求一个整数的反序数。
算法设计:
import math
# 判断素数
def fun(n):
if n <= 1:
return 0; # n<1时显然不是素数,故返回0
if n == 2:
return 1 # n=2,是素数,返回1
if n % 2 == 0:
return 0 # n是偶数,不是素数,返回0
for i in range(3, int(math.sqrt(n) + 1)):
if n % i == 0:
return 0 # n是奇数,不是素数,返回0
i += 2
return 1 # n是除2以外的素数,返回1
if __name__ == "__main__":
count = 0 # 计数器
# 穷举法
for a in range(1, 9 + 1): # 千位
for b in range(0, 9 + 1):
# 百位
for c in range(0, 9 + 1): # 十位
for d in range(1, 9 + 1): # 个位
if fun(a * 1000 + b * 100 + c * 10 + d): # 判断4位整数是否为素数
# 判断4位逆序的整数是否为素数
if fun(a + b * 10 + c * 100 + d * 1000):
if count % 10 == 0: # 每10个数就换行
print()
print("%d " % (a * 1000 + b * 100 + c * 10 + d), end="")
count += 1
print("\n4位可逆素数共有%d个" % count)
3.孪生素数
问题描述:
所谓孪生素数指的是间隔为2的两个相邻素数,因为它们之间的距离已经近得不能再近了,如同孪生兄弟一样,故将这一对素数称为孪生素数。
问题分析:
显然,最小的一对孪生素数是(1,3)。我们可以写出3~100以内的孪生素数,一共有8对,分别是(3,5),(5,7),(11,13),(17,19),(29,31),(41,43),(59,61)和(71,73)。随着数字的增大,孪生素数的分布也越来越稀疏,人工寻找孪生素数变得非常困难。
孪生素数是指若a为素数,且a+2也是素数,则素数a和a+2称为孪生素数。
算法设计:
import math
# 判断n是否为素数
def prime(n):
k = math.sqrt(n) + 1
i = 2
while i <= k:
if n % i == 0:
return 0 # n能被j整除,不是素数,返回0
i += 1
return 1 # n是素数,返回1
if __name__ == "__main__":
count = 0 # 计数器
print("3到1000之间的孪生素数:")
for i in range(3, 1000):
if prime(i) and prime(i + 2):
print("(%-3d, %3d) " % (i, i + 2), end="")
count += 1
if count % 5 == 0: # 每5个数换一行
print()
print("\n1000以内的孪生素数共有%d对" % count)
二、Python 二班作业
1. 黑洞数
问题描述:
黑洞数又称陷阱数,是指任何一个数字不全相同的整数,在经过有限次“重排求差”操作后,总会得到某一个或一些数,这些数即为黑洞数。“重排求差”操作是将组成一个数的各位数字重排,将得到的最大数减去最小数。
例如,207的“重排求差”操作序列是:720-027=693,963-369=594,954-459=495,此时再进行“重排求差”操作不会发生改变。再用208计算一次,也是停止到495,所以495是三位黑洞数。
编程求三位数中的“黑洞数”。
问题分析:
根据“黑洞数”定义,对于任意一个数字不全相同的整数,最后结果总会掉入到一个黑洞圈或黑洞数里,最后结果一旦为黑洞数,无论再重复进行多少次的“重排求差”操作,结果都是一样的,因此可把结果相等作为判断“黑洞数”的依据。
本题关键:分解 3
位整数,重新排列后找到最大值和最小值。
算法设计:
# 原来的两数相减之差
pre_cha = 0
# 当前两数相减之差
cur_cha = 0
# 已经数字
num = 890
#
while True:
# 分解数字
lst = list(str(num))
# 转换类型
lst = [int(i) for i in lst]
# 降序
lst.sort()
# 最小值
mi = lst[0] * 100 + lst[1] * 10 + lst[2]
# 最大值
lst.sort(reverse=True)
ma = lst[0] * 100 + lst[1] * 10 + lst[2]
# 最大值减最小值之差
cur_cha = ma - mi
if cur_cha == pre_cha:
break
num = cur_cha
pre_cha = cur_cha
print(pre_cha)
2. 多项式之和
问题描述:
计算下列多项式的值:
问题分析:
每一项分式的分母都是对应项标记的阶乘。所以只要求出每一项的阶乘再将其倒数和加在一起即为所求多项式的结果。
算法设计:
n = int(input("请输入一个整数n: "))
s = 0 # s记录多项式的和
i = 1
while i <= n: # i控制对应的项数
t = 1 # t记录每一项分式的分母,每次循环之前给t赋初值
j = 1
while j <= i:
t = t * j # 每一项的阶乘
j += 1
s = s + 1 / t
i += 1
print("%f" % s)
3.列出真分数序列
问题描述:
按递增顺序依次列出所有分母为40、分子小于40的最简分数。
问题分析:
分子和分母只有公因数1
的分数,或者说分子和分母是互质数的分数,叫作最简分数,又称既约分数。如2/3
、8/9
、3/8
等就是最简分数。
求分子小于40
的最简分数,可以对分子采用穷举的方法。根据最简分数的定义可知,分子和分母的最大公约数为1
,因此可以利用最大公约数的方法,判定分子与40
是否构成真分数。
算法设计:
print("分母为40,分子小于40的最简分数有:")
n = 0 # 计数器,记录最简分数的个数
for i in range(1, 40): # 穷举40以内的全部分子
num1 = 40 # 分母
num2 = i # 分子
# 采用辗转相除法求出分子与分母的最大公约数
while num2 != 0:
temp = num1 % num2
num1 = num2
num2 = temp
if num1 == 1: # 若最大公约数为1,则为最简真分数
n += 1
print("%2d/40 " % i, end=" ")
if n % 8 == 0: # 每8个一行
print()
三、Python 三班作业
1. 三色球
问题描述:
一个口袋中放有12
个球,已知其中3
个是红的,3
个是白的,6
个是黑的,现从中任取8
个,问共有多少种可能的颜色搭配?
问题分析:
根据问题描述可设任取的8个球中红球为m
个,白球为n
个,则黑球为8-m-n
个。又已知12
个球中有3
个红球、3
个白球、6
个黑球,因此,m
的取值范围为[0,3]
,n
的取值范围为[0,3]
,黑球的个数小于等于6
,即8-m-n≤6
。
算法设计:
由上述分析可知,红、白、黑三种颜色球的个数的取值范围已经确定了,现在要求的是所有可能的颜色搭配情况,因此可以使用循环结构检测m、n范围内的所有可能取值,再代入8-m-n≤6
中进行验证,能够满足条件8-m-n≤6
的那些m
、n
和8-m-n
的组合即为问题的解。
# 从12个球中任取8个,红球m个,白球n个,黑球8-m-n个
# m的取值范围为[0,3],因此n的取值范围为[0,3],黑球的个数小于等于6,即8-m-n≤6
print("\t 红球 \t 白球 \t 黑球")
print("........................")
num = 0
for m in range(0, 4):
for n in range(0, 4):
if 8-m-n <= 6:
num += 1
print("%2d: %d \t\t %d \t\t %d" %(num, m, n, 8-m-n))
2. 求自然数
问题描述:
四个连续的3
位自然数的和是一个在400
到440
之间的三位数,并且能被9
整除,这四个自然数分别是多少?
问题分析:
假设第 1
个自然数为 n
,因存在连续关系,则后 3
个自然数为 n+1
,n+2
,n+3
。且 n+(n+1)+(n+2)+(n+3)
大于等于 400
,小于等于 440
。可分析得到一个结论,任一数字都不可以大于 400
。
算法设计:
for n in range(100,110):
if 4*n+6>=400 and 4*n+6<=440 and (4*n+6) % 9==0:
print(n)
3. 爱因斯坦的数学题
问题描述:
爱因斯坦出了一道这样的数学题:有一条长阶梯,若每步跨2
阶,则最后剩一阶,若每步跨3
阶,则最后剩2
阶,若每步跨5
阶,则最后剩4
阶,若每步跨6
阶,则最后剩5
阶。只有每次跨7
阶,最后才正好一阶不剩。请问在1
到1000
内,有多少个数能满足?
问题分析:
此问题的本质就是求解一个同时能满足如下条件的数字。
- 被
2
整除余1
- 被
3
整除余数2
- 被
5
整除余数为4
- 被
6
整除余数为5
- 被
7
整除余数为0
。
算法设计:
sum = 0
for i in range(7, 1000 + 1,2):
# 阶梯数所满足的条件
if (i % 7 == 0) and (i % 6 == 5) and (i % 5 == 4) and (i % 3 == 2):
sum += 1 # sum记录1~n之间满足条件的阶梯个数
print("%d" % i)
print("在1-%d之间,有%d个数可以满足爱因斯坦对阶梯的要求。" % (1000, sum))