from CoTime import*from functools import*from fn import _
print("import over")
import over
"""
题目
"""# 网上抄的print("Copy")
t = CoTime()##print()print(t.cost())#自己写的#优缺点:print("My")
t = CoTime()##print()print(t.cost())
"""
0 ~ 9这10个数字可以组成多少不重复的3位数?
"""# 网上抄的print("Copy")
t = CoTime()#
l =range(10)
count =0for a in l[1:]:for b in l:if a == b:continue#过滤a == bfor c in l:if c != a and c != b:#过滤a == c, b == c
count +=1print(count)#print(t.cost())#自己写的print("My")
t = CoTime()#
a =range(10)
b =range(1,10)
count =0for x in b:for y in a:if x == y:continuefor z in a:if z == x or z == y:continue
count +=1print(count)#print(t.cost())
Copy
648
耗时0.000秒
My
648
耗时0.000秒
"""
1.问题描述:
水仙花数是指一个n位数(n≥3),它的每个位上的数字的n次幂之和等于它本身。
例如:1 ^ 3+5 ^ 3+3 ^ 3=153。
求100 ~ 999之间所有的水仙花数。
"""# 网上抄的print("Copy")
t = CoTime()#defisArmstrongNumber(n):
a =[]
t = n
while t >0:
a.append(t %10)
t = t //10
k =len(a)returnsum([x ** k for x in a])== n
for x inrange(100,1000):if isArmstrongNumber(x):print(x,end="\t")#print()print(t.cost())#自己写的#网上抄的通用性更好print("My")
t = CoTime()#
a =range(1,10)
b =range(10)
n =3for x in a:for y in b:for z in b:if x ** n + y ** n + z ** n == x *100+ y *10+ z:print('{}{}{}'.format(x, y, z), end='\t')#print()print(t.cost())
"""
完全数(Perfect number),又称完美数或完备数,是一些特殊的自然数。
它所有的真因子(即除了自身以外的约数)的和(即因子函数),恰好等于它本身。
例如,第一个完全数是6,它有约数1、2、3、6,除去它本身6外,其余3个数相加,1+2+3=6。
第二个完全数是28,它有约数1、2、4、7、14、28,除去它本身28外,其余5个数相加,1+2+4+7+14=28。
编程求10000以内的完全数。
"""print('copy')
t = CoTime()defisPerfectNumber(n):
a =1
b = n
s =0while a < b:if n % a ==0:
s += a + b
a +=1
b = n / a
if a == b and a * b == n:
s += a
return s - n == n
for k inrange(2,10000):if isPerfectNumber(k):print(k, end='\t')print()print(t.cost())print('my')
t = CoTime()# 网上抄的更节约时间,自己写的更无脑defGetYinzi(n):
a =range(1, n)
re1 =[x for x in a if n % x ==0]return re1
for k inrange(2,10000):if(sum(GetYinzi(k))== k):print(k, end='\t')print()print(t.cost())
"""
220的真因数之和为1+2+4+5+10+11+20+22+44+55+110=284
284的真因数之和为1+2+4+71+142=220
毕达哥拉斯把这样的数对A、B称为相亲数:A的真因数之和为B,而B的真因数之和为A。
求100000以内的相亲数。
"""# 网上抄的print("Copy")
t = CoTime()#defsumOfFactors(k):
p =1
q = k
s =0while p < q:if k % p ==0:
s += p + q
p +=1
q = k // p
if k == p * q and p == q:
s += p
return s - k
for x inrange(2,100000):
y = sumOfFactors(x)if y > x == sumOfFactors(y):print(x, y, end='\t')#print()print(t.cost())#自己写的#优缺点:print("My")
t = CoTime()#
@lru_cache()defGetYinziSum(n):"""
因为常常要用这个真因子,就写一个效率的函数,
参考上面一个例子
:param n:
:return:
"""
re1 =[]
a =1
b = n
while a < b:if n % a ==0:
re1.append(a)if b != a and b != n:
re1.append(b)
a +=1
b = n // a
return re1
for i inrange(1,100000):
i2 =sum(GetYinziSum(i))if i2 > i ==sum(GetYinziSum(i2)):print(i, i2, end='\t')#print()print(t.cost())
"""
黑洞数 ->中
1.问题描述:
黑洞数又称陷阱数,是类具有奇特转换特性的整数。任何一个数字不全相同的整数,经有限“重排求差”操作,总会得到某一
个或一些数,这些数即为黑洞数。“重排求差”操作即把组成该数的数字重排后得到的最大数减去重排后得到的最小数。
举个例子,3位数的黑洞数为495.
简易推导过程:随便找个数,如297,3个位上的数从小到大和从大到小各排一次,为972和279,相减得693。
按上面做法再做一次,得到594,再做一次,得到495,之后反复都得到495。
验证4位数的黑洞数为6174。
"""# 网上抄的print("Copy")
t = CoTime()#deffun(n):
a =[int(c)for c instr(n)]
a.sort()
s1 =reduce(lambda x, y:10* x + y, a[::-1])
s2 =reduce(lambda x, y:10* x + y, a)return n if s1 - s2 == n else fun(s1 - s2)for i inrange(1000,10000):
x = fun(i)if x !=6174and x !=0:print(i, x)#print()print(t.cost())#自己写的#优缺点:fn比lamda耗时,也不更容易懂,稍微好写点print("My")
t = CoTime()#
@lru_cache()deffun(n):
a =[int(x)for x instr(n)]
a.sort()
n1 =reduce(_*10+_, a)# 小到大
n2 =reduce(_*10+_, a[::-1])
n3 = n2 - n1
if n3 == n:return n
else:return fun(n3)for i inrange(1000,10000):
x = fun(i)if x !=6174and x !=0:print(i, x)#print()print(t.cost())
Copy
耗时0.158秒
My
耗时0.722秒
"""
勾股数 ->易
1.问题描述:
所谓勾股数,一般是指能够构成直角三角形3条边的3个正整数(a,b,c)。
即a²+b²=c²,a,b,cΣN
求1000以内的勾股数的数量(太多了,不写出来了)。
"""# 网上抄的print("Copy")
t = CoTime()#import math
sum1 =0for a inrange(1,1000):for b inrange(a,1000):
c = math.sqrt(a * a + b * b)if c >1000:breakif c.is_integer():
sum1 +=1print(sum1)#print()print(t.cost())#自己写的#优缺点:注意上面,math的是整数的表述,并没有微小的误差print("My")
t = CoTime()#
sum1 =0for x inrange(1,1000):for y inrange(x,1000):
a = x **2+ y **2
z =int(math.sqrt(a))if z >1000:breakif a == z **2:
sum1 +=1print(sum1)#print()print(t.cost())
Copy
881
耗时0.212秒
My
881
耗时0.695秒
"""
自守数 ->易
1.问题描述:
如果某个数的平方的末尾几位等于这个数,那么就称这个数为自守数。显然,5和6是一位自守数(5 * 5=25,6 * 6=36)。 25 * 25=625,76 * 76=5776,所以25和76是两位自守数。
求10000以内的自守数。
"""# 网上抄的print("Copy")
t = CoTime()#for n inrange(1,10000):
l =len(str(n))
t1 = n * n %(10** l)if t1 == n:print(n,end='\t')#print()print(t.cost())#自己写的#优缺点:居然还快一点,更容易字面理解print("My")
t = CoTime()#for n inrange(1,10000):
n2 =n*n
ifstr(n2).endswith(str(n)):print(n,end='\t')#print()print(t.cost())
"""
3位反序数 ->中
1.问题描述:
所谓反序数,即有这样成对的数,其特点是其中一个数的数字排列顺序完全颠倒过来,就变成另一个数,
如102和201,36和63等,简单的理解就是顺序相反的两个数,我们把这种成对的数互称为反序数。反序数唯一不可能出现以0结尾的数。
一个3位数各位上的数字都不相同,它和它的反序数的乘积是280021,这个3位数应是多少?
"""# 网上抄的print("Copy")
t = CoTime()#for b inrange(10):for a inrange(1,10):if a == b:continuefor c inrange(a +1,10):if c == b:continue
t1 =100* a +10* b + c
t2 =100* c +10* b + a
if t1 * t2 ==280021:print(t1, t2, end='\t')#print()print(t.cost())#自己写的#优缺点:因为280021的因子很少,# 后面虽然看起来很多,但只需要算一次print("My")
t = CoTime()#for i inrange(100,500):if280021% i ==0:
i2 =280021// i
s1 =[int(x)for x instr(i)]
s2 =[int(x)for x instr(i2)]iflen(s1)==len(s2)==3and s2[2]== s1[0] \
and s1[1]== s2[1]and s2[0]== s1[2]:print(i, i2, end='\t')#print()print(t.cost())
Copy
367 763
耗时0.001秒
My
367 763
耗时0.001秒
"""
素数 ->中
1.问题描述:
素数(质数)指的是不能被分解的数,除了1和它本身之外就没有其他数能够整除。
求100以内的所有素数。
"""# 网上抄的print("Copy")
t = CoTime()#defisPrimeNumber(n, s):for k in s:if k * k > n:breakif n % k ==0:returnNonereturn n
prime =[]for n inrange(2,100):
res = isPrimeNumber(n, prime)if res: prime.append(res)print(prime)#print()print(t.cost())#自己写的#优缺点:没什么好讲的print("My")
t = CoTime()##print()print(t.cost())
"""
金蝉素数 ->中
1.问题描述:
某古寺的一块石碑上依稀刻有一些神秘的自然数。
专家研究发现:这些数是由1,3,5,7,9这5个奇数字排列组成的5位素数,
同时去掉它的最高位与最低位数字后的3位数还是素数,
同时去掉它的高二位与低二位数字后的一位数还是素数。
因此人们把这些神秘的素数称为金蝉素数,
喻意金蝉脱壳之后仍为美丽的金蝉。
试求出石碑上的金蝉素数。
"""# 网上抄的print("Copy")
t = CoTime()## 1. 生成 1,3,5,7,9 全排列, 每种排列是一个元组# 2. 元组转换成数字 (例: 13579,357,159)# 3. 检测3个数字是素数,如全是素数则是金蝉数import math
defisPrimeNum(n):for k inrange(2,int(math.sqrt(n)+1)):if n % k ==0:returnFalsereturnTruefrom itertools import permutations
for p in permutations([1,3,5,7,9],5):# (3,5,7), (1,5,9), (1,3,5,7,9) for l in(p[1:-1], p[::2], p):
s =reduce(lambda x, y:10* x + y, l)ifnot isPrimeNum(s):breakelse:print(p)#print()print(t.cost())#自己写的#优缺点:学会了全排列print("My")
t = CoTime()#import math
@lru_cache()defisPrimeCh(n):for k inrange(2,int(math.sqrt(n)+1)):if n % k ==0:returnFalsereturnTruefrom itertools import permutations
for p in permutations([1,3,5,7,9],5):for l in([p[2]], p[1:-1], p):
s =reduce(lambda x, y: x *10+ y, l)ifnot isPrimeCh(s):breakelse:print(p)#print()print(t.cost())
"""
可逆素数 ->中
1.问题描述:
编写程序找出1 ~ 900之间的所有可逆素数(可逆素数是指一个素数的各位数值顺序颠倒后得到的数仍为素数,如113、311)。
"""
m=1000# 网上抄的print("Copy")
t = CoTime()## 解题步骤:# 1. 用筛法找到900以内素数表# 2. 迭代表内所有数,是素数的检测它的反序数是否是素数。# 3. 2条件为真,打印这俩个素数。defgetPrimeTable(n):
pt =[True]* n
for p inrange(2, n):ifnot pt[p]:continuefor i inrange(p * p, n, p):
pt[i]=Falsereturn pt
pt = getPrimeTable(m)for p inrange(10, m):ifnot pt[p]:continue
q =int(str(p)[::-1])if p != q < m and pt[q]:print(p,q,end='\t')
pt[q]=False#print()print(t.cost())#自己写的#优缺点:明显筛法是更节约时间的print("My")
t = CoTime()#
@lru_cache()defisPrimeCh(n):for k inrange(2,int(math.sqrt(n)+1)):if n % k ==0:returnFalsereturnTruefor p inrange(10,m):ifnot isPrimeCh(p):continue
q =int(str(p)[::-1])if p <q <m and isPrimeCh(q):print(p,q,end='\t')#print()print(t.cost())
"""
回文素数 ->中
1.问题描述:
所谓回文素数是指,对一个整数n从左向右和从右向左读结果值相同且是素数,即称为回文素数。
求不超过1000的回文素数。
"""
m =1000# 网上抄的'''
不知道它哪里错了,不找了
百度找了答案是:
11,101,131,151,181,191,313,353,373,383,727,757,787,797,919,929等等
'''print("Copy")
t = CoTime()#import math
defisPrimeNumber(num):
i =2
x = math.sqrt(num)while i < x:if num % i ==0:returnFalse
i +=1returnTruedefReverse(num):
rNum =0while num:
rNum = rNum *10+ num %10
num /=10return rNum
defRPrimeNumber(num):
arr =[]
i =2while i < num:if isPrimeNumber(i)and i == Reverse(i):
arr.append(i)
i +=1return arr
print(RPrimeNumber(m))#print()print(t.cost())#自己写的#优缺点:print("My")
t = CoTime()#
@lru_cache()defisPrimeCh(n):for k inrange(2,int(math.sqrt(n)+1)):if n % k ==0:returnFalsereturnTruefor i inrange(11, m):if isPrimeCh(i):
i2 =int(str(i)[::-1])if i2 == i and isPrimeCh(i2):print(i, end='\t')#print()print(t.cost())
"""
哥德巴赫猜想 ->中
1.问题描述:
众所周知,哥德巴赫猜想的证明是一个世界性的数学难题,至今未能完全解决。我国著名数学家陈景润为哥德巴赫猜想的证明作出过杰出的贡献。
所谓哥德巴赫猜想是说任何一个大于2的偶数都能表示成为两个素数之和。
编写程序,验证指定范围内哥德巴赫猜想的正确性,也就是近似证明哥德巴赫猜想。
"""
m1 =6
m2 =100000# 网上抄的print("Copy")
t = CoTime()#defisPrimeNumber(n, s):for k in s:if k **2> n:breakif n % k ==0:returnFalsereturnTruedeffun():
s =[3]for n inrange(m1, m2,2):
f =Falsefor k in s:
t = n - k
if t < k:breakif isPrimeNumber(t, s):if t > s[-1]: s.append(t)
f =Truebreakifnot f:raise Exception
fun()#print()print(t.cost())#自己写的#优缺点:print("My")
t = CoTime()#
@lru_cache()defisPrimeCh(n):for k inrange(2,int(math.sqrt(n)+1)):if n % k ==0:returnFalsereturnTruefor i inrange(m1, m2,2):for j inrange(2, i //2+1):
f =Falseif isPrimeCh(j):
k = i - j
if isPrimeCh(k):
f =Truebreakifnot f:print(i)#print()print(t.cost())
Copy
耗时1.220秒
My
耗时0.420秒
"""
等差素数数列 ->中
1.问题描述:
类似7、37、67、97、107、137、167、197,这样由素数组成的数列叫做等差素数数列。素数数列具有项数的限制,一般指素数数列的项数有多少个连续项,最多可以存在多少个连续项。
编程找出100以内的等差素数数列。
"""# 网上抄的print("Copy")
t = CoTime()## 解题步骤:# 1. 筛法找到100所有素数# 2. 对于素数list内素有俩两组合,构造等差数列a0, a1项# 3. 计算出a2, 查表判断a2是否是素数,是素数则能构成素数等差序列, 计算a3...deffindAllPrime(n):
pt =[True]* n
prime =[]for p inrange(2, n):ifnot pt[p]:continue
prime.append(p)for i inrange(p * p, n, p):
pt[i]=Falsereturn prime, pt
prime, pt = findAllPrime(100)for i inrange(len(prime)):for j inrange(i +1,len(prime)):
a0, a1 = prime[i], prime[j]
an = a1 + a1 - a0
s =[]while an <100and pt[an]:
s.append(an)
an += a1 - a0
if s:print([a0, a1]+ s,end='\t')#print()print(t.cost())#自己写的#优缺点:print("My")
t = CoTime()##print()print(t.cost())