# -*- coding: utf-8 -*-
"""
Created on Thu Nov 17 16:52:17 2016
@author: alis
"""
'''趣味百题之趣味整数'''
# 求一个数的所有因子
def factors(num):
p = 1
q = num
a = []
while p < q:
if num % p == 0:
a.append(p);a.append(q)
p += 1
q = num/p
a.sort()
return a
z = factors(1054)
#1、0-9这10个数字可以组成多少不重复的3位数?
count = 0
for i in range(1,10):
for j in range(10):
if (i == j):continue # 如果 i==j ,过滤
for k in range(10):
if (i != k) and (j != k):
print i,j,k
count += 1
print count
'''2 水仙花数是指一个n位数(n≥3),它的每个位上的数字的n次幂之和等于它本身。
例如:1^3+5^3+3^3=153。
求100~999之间所有的水仙花数。'''
for i in range(100,1000):
num2str = str(i)
mat = list(num2str)
z = (int(mat[0]))**3 + (int(mat[1]))**3 + (int(mat[2]))**3
if z == i:
print "%d 是水仙花数!" %i
'''3. 完全数(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以内的完全数。 '''
# 方法1
from numpy import *
import time
begin_time = time.clock()
for i in range(2,50000):
z = int(sqrt(i))
vector = []
for j in range(1,z+1):
if mod(i,j) == 0:
temp = i/j
vector.append(j)
vector.append(temp)
vector.sort()
del vector[-1]
if sum(vector) == i:
print "%d 是完全数" %i
end_time = time.clock()
print "运行时间为%f"%(end_time - begin_time)
#方法2
begin_time = time.clock()
for i in range(2,500000):
z = factors(i)
del z[-1]
if sum(z) == i:
print "%d 是完全数" %i
end_time = time.clock()
print "运行时间为%f"%(end_time - begin_time)
'''4. 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以内的相亲数。'''
#方法一:
begin_time = time.clock()
def find_num(num):
sqi = int(sqrt(num))
mat = []
for j in range(1,sqi+1):
if mod(num,j) == 0:
temp = num/j
mat.append(j)
mat.append(temp)
mat.sort()
del mat[-1]
sum_mat = sum(mat)
return sum_mat
for i in range(2,100000):
sum1 = find_num(i)
sum2 = find_num(sum1)
if i == sum2:
print "%d 与 %d 是相亲数" %(sum1,sum2)
end_time = time.clock()
print (end_time - begin_time)
#方法2
begin_time = time.time()
def sumOfFactors(k):
p = 1
q = k
s = 0
a = []
while p < q:
if k % p == 0:
s += p + q
a.append(p);a.append(q)
p += 1
q = k / p
if k == p * q and p == q:
s += p
return s - k
def fun(start, end):
for x in range(start, end):
y = sumOfFactors(x)
if x < y and sumOfFactors(y) == x:
print x, y
fun(2, 100000)
end_time = time.time()
print (end_time - begin_time)
'''5.
黑洞数又称陷阱数,是类具有奇特转换特性的整数。任何一个数字不全相同的整数,经有
限“重排求差”操作,总会得到某一个或一些数,这些数即为黑洞数。“重排求差”操作即把组成
该数的数字重排后得到的最大数减去重排后得到的最小数。
举个例子,3位数的黑洞数为495.
简易推导过程:随便找个数,如297,3个位上的数从小到大和从大到小各排一次,为972和279,
相减得693。按上面做法再做一次,得到594,再做一次,得到495,之后反复都得到495。
验证4位数的黑洞数为6174。'''
def diff_str(n):
num2str = str(n)
num = list(num2str)
num.sort()
small = '';big = ''
for i in range(len(num)):
small = small + str(num[i])
big = big + str(num[len(num)-i-1])
diff = int(big) - int(small)
print "%d - %d = %d"%(int(big),int(small),diff)
if diff == 6174:
print "计算结束,6174是黑洞数"
else:
diff_str(diff)
diff_str(8260)
# 6. 求1000以内的勾股数。
import math
for i in range(1,1000):
for j in range(i+1,1000):
c = i**2 + j**2
if c > 1000:break
else:
print"1000以内勾股数为%d,%d,%d" %(i,j,c)
'''7.
如果某个数的平方的末尾几位等于这个数,那么就称这个数为自守数。显然,5和6是一位自守数
(5*5=25,6*6=36)。 25*25=625,76*76=5776,所以25和76是两位自守数。求10000以内的自守数。'''
for i in range(1,100000):
len_i = len(str(i))
temp = list(str(i**2))
a = ''
for j in range(len(temp)-len_i,len(temp)):
a = a + str(temp[j])
if i == int(a):
print "%d 是自守数!"%i
else:continue
'''8.
所谓反序数,即有这样成对的数,其特点是其中一个数的数字排列顺序完全颠倒过来,就变成另一个
数,如102和201,36和63等,简单的理解就是顺序相反的两个数,我们把这种成对的数互称为反序数。
反序数唯一不可能出现以0结尾的数。一个3位数各位上的数字都不相同,
它和它的反序数的乘积是280021,这个3位数应是多少?'''
for i in range(100,1000):
a = i/100
b = mod(i,100)/10
c = mod(i,10)
re_num = c*100 + b*10 + a
if re_num * i == 280021:
print "这个三位数是%d"%i
break
else:
continue
"""
Created on Thu Nov 17 16:52:17 2016
@author: alis
"""
'''趣味百题之趣味整数'''
# 求一个数的所有因子
def factors(num):
p = 1
q = num
a = []
while p < q:
if num % p == 0:
a.append(p);a.append(q)
p += 1
q = num/p
a.sort()
return a
z = factors(1054)
#1、0-9这10个数字可以组成多少不重复的3位数?
count = 0
for i in range(1,10):
for j in range(10):
if (i == j):continue # 如果 i==j ,过滤
for k in range(10):
if (i != k) and (j != k):
print i,j,k
count += 1
print count
'''2 水仙花数是指一个n位数(n≥3),它的每个位上的数字的n次幂之和等于它本身。
例如:1^3+5^3+3^3=153。
求100~999之间所有的水仙花数。'''
for i in range(100,1000):
num2str = str(i)
mat = list(num2str)
z = (int(mat[0]))**3 + (int(mat[1]))**3 + (int(mat[2]))**3
if z == i:
print "%d 是水仙花数!" %i
'''3. 完全数(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以内的完全数。 '''
# 方法1
from numpy import *
import time
begin_time = time.clock()
for i in range(2,50000):
z = int(sqrt(i))
vector = []
for j in range(1,z+1):
if mod(i,j) == 0:
temp = i/j
vector.append(j)
vector.append(temp)
vector.sort()
del vector[-1]
if sum(vector) == i:
print "%d 是完全数" %i
end_time = time.clock()
print "运行时间为%f"%(end_time - begin_time)
#方法2
begin_time = time.clock()
for i in range(2,500000):
z = factors(i)
del z[-1]
if sum(z) == i:
print "%d 是完全数" %i
end_time = time.clock()
print "运行时间为%f"%(end_time - begin_time)
'''4. 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以内的相亲数。'''
#方法一:
begin_time = time.clock()
def find_num(num):
sqi = int(sqrt(num))
mat = []
for j in range(1,sqi+1):
if mod(num,j) == 0:
temp = num/j
mat.append(j)
mat.append(temp)
mat.sort()
del mat[-1]
sum_mat = sum(mat)
return sum_mat
for i in range(2,100000):
sum1 = find_num(i)
sum2 = find_num(sum1)
if i == sum2:
print "%d 与 %d 是相亲数" %(sum1,sum2)
end_time = time.clock()
print (end_time - begin_time)
#方法2
begin_time = time.time()
def sumOfFactors(k):
p = 1
q = k
s = 0
a = []
while p < q:
if k % p == 0:
s += p + q
a.append(p);a.append(q)
p += 1
q = k / p
if k == p * q and p == q:
s += p
return s - k
def fun(start, end):
for x in range(start, end):
y = sumOfFactors(x)
if x < y and sumOfFactors(y) == x:
print x, y
fun(2, 100000)
end_time = time.time()
print (end_time - begin_time)
'''5.
黑洞数又称陷阱数,是类具有奇特转换特性的整数。任何一个数字不全相同的整数,经有
限“重排求差”操作,总会得到某一个或一些数,这些数即为黑洞数。“重排求差”操作即把组成
该数的数字重排后得到的最大数减去重排后得到的最小数。
举个例子,3位数的黑洞数为495.
简易推导过程:随便找个数,如297,3个位上的数从小到大和从大到小各排一次,为972和279,
相减得693。按上面做法再做一次,得到594,再做一次,得到495,之后反复都得到495。
验证4位数的黑洞数为6174。'''
def diff_str(n):
num2str = str(n)
num = list(num2str)
num.sort()
small = '';big = ''
for i in range(len(num)):
small = small + str(num[i])
big = big + str(num[len(num)-i-1])
diff = int(big) - int(small)
print "%d - %d = %d"%(int(big),int(small),diff)
if diff == 6174:
print "计算结束,6174是黑洞数"
else:
diff_str(diff)
diff_str(8260)
# 6. 求1000以内的勾股数。
import math
for i in range(1,1000):
for j in range(i+1,1000):
c = i**2 + j**2
if c > 1000:break
else:
print"1000以内勾股数为%d,%d,%d" %(i,j,c)
'''7.
如果某个数的平方的末尾几位等于这个数,那么就称这个数为自守数。显然,5和6是一位自守数
(5*5=25,6*6=36)。 25*25=625,76*76=5776,所以25和76是两位自守数。求10000以内的自守数。'''
for i in range(1,100000):
len_i = len(str(i))
temp = list(str(i**2))
a = ''
for j in range(len(temp)-len_i,len(temp)):
a = a + str(temp[j])
if i == int(a):
print "%d 是自守数!"%i
else:continue
'''8.
所谓反序数,即有这样成对的数,其特点是其中一个数的数字排列顺序完全颠倒过来,就变成另一个
数,如102和201,36和63等,简单的理解就是顺序相反的两个数,我们把这种成对的数互称为反序数。
反序数唯一不可能出现以0结尾的数。一个3位数各位上的数字都不相同,
它和它的反序数的乘积是280021,这个3位数应是多少?'''
for i in range(100,1000):
a = i/100
b = mod(i,100)/10
c = mod(i,10)
re_num = c*100 + b*10 + a
if re_num * i == 280021:
print "这个三位数是%d"%i
break
else:
continue
本文通过编程方式解答了一系列有趣的数学题目,包括寻找水仙花数、完全数、相亲数等,并验证了黑洞数的存在,还涉及勾股数和自守数的求解。
2322

被折叠的 条评论
为什么被折叠?



