Python3 欧拉计划 问题21-25

Python3 欧拉计划 问题21-25_第1张图片
EulerProject.png

问题16-20参见: http://www.jianshu.com/p/63b4f80bd84e

21、亲和数

  记d(n)为n的所有真因数(小于n且整除n的正整数)之和。如果d(a) = b且d(b) = a,且a ≠ b,那么a和b构成一个亲和数对,a和b被称为亲和数。例如,220的真因数包括1、2、4、5、10、11、20、22、44、55和110,因此d(220) = 284。284的真因数包括1、2、4、71和142,因此d(284) = 220。说明284和220是亲和数
  求所有小于10000的亲和数的和。

Python3解答
def fan_sum(number):#计算真因数的和
    hu=[1]
    for i in range(2,int(number**0.5)+1):
        if number%i==0 and number>i:
            hu.append(i)
            if number!=i**2:
                hu.append(number/i)
    return sum(f for f in hu)
an_dict={}
for i in range(1,10001):
    an_dict[i]=fan_sum(i)#存储真因数和的字典

fan=0
for i in range(1,10001):    
    try:
        if an_dict[an_dict[i]]==i and an_dict[i]!=i:#寻找d[a]=b and d[b]= a
            fan+=i
    except KeyError:
        pass
print(fan)
答案:31626

22、姓名之分

  文本names.txt中包含了五千多个姓名,首先将姓名按字母顺序排列,然后算出每个姓名字母的和值,最后乘以该姓名排列后的位置,以计算出姓名之分。例如,按照字母顺序排列后,姓名COLIN的位置是938,其字母的和值是3 + 15 + 12 + 9 + 14 = 53。因此COLIN的姓名之分是938 × 53 = 49714。
  计算文件中所有姓名的姓名之分的和。

Python3解答
with open(r'C:\Users\GWT9\Desktop\secries11.txt')as an_file:#读取姓名数据
    fan=an_file.read()
    fan_an= sorted(fan.replace('"', '').split(','))#姓名排序
def fan_sumq(stit):#计算姓名的字母的和值
    return sum(ord(i)-64 for i in stit)
print(sum(fan_sumq(fan_an[i])*(i+1) for i in range(0,len(fan_an))))
答案: 871198282

23、非盈数之和的和

  完全数是指真因数之和等于自身的那些数。例如,28的真因数之和为1 + 2 + 4 + 7 + 14 = 28,因此28是一个完全数。一个数n被称为亏数,如果它的真因数之和小于n;反之则被称为盈数。由于12是最小的盈数,它的真因数之和为1 + 2 + 3 + 4 + 6 = 16,所以最小的能够表示成两个盈数之和的数是24。通过数学分析可以得出,所有大于28123的数都可以被写成两个盈数的和;因此28123是不能被分成两个盈数的和的最大的数的上界。
  找出所有不能被写成两个盈数之和的正整数的和。

Python3解答
def fan_sum(number):#判断是否是盈数
    hu=[1]
    for i in range(2,int(number**0.5)+1):
        if number%i==0 and number>i:
            hu.append(i)
            if number!=i**2:
                hu.append(number/i)
    if sum(i for i in hu)>number:
        return True
    
def an_sum(number):
    an,fan=set(),0
    for i in range(1,number+1):
        if fan_sum(i):
            an.add(i)
        if not any((i-j) in an for j in an):#判断是否可以写成两个盈数的和
            fan+=i
    return fan
print(an_sum(28123))
答案:4179871

24、字典序排列

  排列指的是将一组物体进行有顺序的放置。例如,3124是数字1、2、3、4的一个排列。如果把所有排列按照数字大小或字母先后进行排序,我们称之为字典序排列。0、1、2的字典序排列是:012 021 102 120 201 210 。
  数字0、1、2、3、4、5、6、7、8、9的字典序排列中第一百万位的排列是。

Python3解答
#思路:100万=a*9!+b*8!+……+k*0!
def an_pro(num):#计算阶乘
    if num==0:
        return 1
    else:
        nu=1
        while num>0:
            nu*=num
            num-=1
        return nu
#计算每个阶乘前面的数字的位置编号
def fan_lis(number):#number=100万,count=10,lis存储过程中的数字
    anlist=[]#存储过程中的数字
    digitcount=9
    while number>=0:
        jiecheng=an_pro(digitcount)#计算count个数字的全排列组成的数字个数
        ji=int(number/jiecheng)#计算阶乘倍数
        anlist.append(ji)#存储
        nu=ji*jiecheng
        number-=nu
        digitcount-=1
        if digitcount==0:
            break
    anlist.append(0)
    return anlist
fan=fan_lis(999999)#第100万位的数字
#将上面程序的位置编号转化为对应的数字
fanfan=list(range(0,10))
fan_an=[]#存储对应的数字
for i in range(0,len(fan)):
    fan_an.append(fanfan[fan[i]])
    fanfan.remove(fanfan[fan[i]])
#输出最终的数字  
an_str=''
for i in fan_an:
    an_str+=str(i)#最终输出数字
print(an_str)
答案:2783915460

25、1000位的斐波那契数

  斐波那契数列是按如下递归关系定义的数列:
      F1 = 1 F2 = 1
      Fn = Fn−1 + Fn−2
因此斐波那契数列的前12项分别是:
F1 = 1
F2 = 1
F3 = 2
F4 = 3
F5 = 5
F6 = 8
F7 = 13
F8 = 21
F9 = 34
F10 = 55
F11 = 89
F12 = 144
不难看出,第一个有3位数字的是第12项F12。
  在斐波那契数列中,第一个有1000位数字的是第几项。

Python3解答
def an_fib(num):
    an,fan,an_fan=1,1,2
    while len(str(fan))

持续更新,欢迎讨论,敬请关注!!!

你可能感兴趣的:(Python3 欧拉计划 问题21-25)