鱼C论坛

 找回密码
 立即注册
查看: 5469|回复: 26

题目21:计算10000以下所有相亲数之和

[复制链接]
发表于 2015-4-23 16:16:53 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
本帖最后由 欧拉计划 于 2015-4-23 16:19 编辑
Amicable numbers

Let d(n) be defined as the sum of proper divisors of n (numbers less than n which divide evenly into n).

If d(a) = b and d(b) = a, where a ≠ b, then a and b are an amicable pair and each of a and b are called amicable numbers.

For example, the proper divisors of 220 are 1, 2, 4, 5, 10, 11, 20, 22, 44, 55 and 110; therefore d(220) = 284. The proper divisors of 284 are 1, 2,

4, 71 and 142; so d(284) = 220.

Evaluate the sum of all the amicable numbers under 10000.

题目:

d(n) 定义为 n 的所有真因子(小于 n 且能整除 n 的整数)之和。

如果 d(a) = b 并且 d(b) = a, 且 a ≠ b, 那么 a 和 b 就是一对相亲数(amicable pair),并且 a 和 b 都叫做亲和数(amicable number)。

例如 220 的真因子是 1, 2, 4, 5, 10, 11, 20, 22, 44, 55 和 110; 因此 d(220) = 284. 284 的真因子是 1, 2, 4, 71 和 142; 所以 d(284) = 220.

计算 10000 以下所有亲和数之和。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2016-8-21 21:04:01 | 显示全部楼层
结果为:31626
代码如下:
  1. result = []
  2. for n in range(1,10000):
  3.     factor1 = []
  4.     s = 0
  5.     for i in range(1,n):
  6.         if n % i == 0:
  7.             factor1.append(i)
  8.             s += i
  9.     factor2 = []
  10.     s2 = 0
  11.     for j in range(1,s):
  12.         if s % j == 0:
  13.             factor2.append(j)
  14.             s2 += j
  15.     if (s2 == n) and (s2 != s):
  16.         result.append(n)
  17. final = sum(result)
  18. print(final)
  19.             
复制代码

计算效率比较低,求后续优化
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2016-8-27 17:29:36 | 显示全部楼层
  1. def d(x):
  2.     n = 0
  3.     for i in range(1,x):
  4.         if x%i == 0:
  5.             n += i
  6.     return n



  7. result = 0



  8. for x in range(2,10000):
  9.     if d(x) == x:
  10.         continue
  11.     if d(d(x)) == x:
  12.         result += x

  13. print(result//2)
复制代码
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2016-8-28 22:09:55 | 显示全部楼层
  1. def TrueBec(x):
  2.     list1=[]
  3.     for i in range(1,x):
  4.         if x % i == 0:
  5.             list1.append(i)
  6.     return sum(list1)


  7. def Judg(i):
  8.     temp = TrueBec(i)
  9.     if i == TrueBec(temp) and i != temp:
  10.         return True


  11. list1 = []


  12. for i in range(10000):
  13.     if Judg(i):
  14.         list1.append(i)


  15. print(sum(list1))
复制代码

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2016-9-19 08:30:38 | 显示全部楼层
本帖最后由 jerryxjr1220 于 2016-10-11 23:07 编辑
  1. 31626
  2. [Finished in 0.2s]
复制代码

  1. def y(n):
  2.         lst = [1]
  3.         for i in range(2,int(n**0.5+1)):
  4.                 if n%i == 0:
  5.                         lst.append(i)
  6.                         lst.append(int(n//i))
  7.         return lst

  8. master = [0]*100000
  9. for j in range(1,10001):
  10.         if j == 1:
  11.                 master[j] = 1
  12.         elif j == 2:
  13.                 master[j] = 1
  14.         else:
  15.                 master[j] = sum(y(j))
  16. summ = 0
  17. for k in range(1,10000):
  18.         if k == master[master[k]] and master[k] != k:
  19.                 print master[k], k
  20.                 summ += k
  21. print summ
复制代码
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2016-10-26 17:15:11 | 显示全部楼层
def getSum(num):
    listnum = []
    for i in range(1, int(num/2) + 1):
        if num % i == 0:
            listnum.append(i)
    return sum(listnum)

list1 = []
for i in range(1, 10000):
    if getSum(getSum(i)) == i:
        list1.append(i)
print list1
print sum(list1)

40284
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2017-1-11 15:08:39 | 显示全部楼层
  1. # encoding:utf-8
  2. # 10000以内的亲和数之和
  3. from time import time
  4. def getFactorsSum(N):
  5.     l_result = [1]
  6.     for t in range(2,int(N**0.5)+1):
  7.         if N%t == 0:
  8.             l_result.append(t)
  9.             l_result.append(N//t);
  10.     return sum(l_result)
  11. def euler020():
  12.     l_r = []
  13.     dic_sum = {}
  14.     for N in range(1,10001):
  15.         dic_sum[N] = getFactorsSum(N)
  16.     for i in range(1,10001):
  17.         if i == dic_sum.get(dic_sum[i]) and i != dic_sum[i]:
  18.             l_r.append(i)
  19.             l_r.append(dic_sum[i])
  20.     s = set(l_r)
  21.     return s
  22. if __name__ == '__main__':
  23.     start = time()
  24.     print(sum(euler020()))
  25.     print('cost %.6f sec' % (time() - start))
复制代码


31626
cost 0.132000 sec
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2017-1-18 20:11:34 | 显示全部楼层
此代码使用matlab编程
Problem21所用时间为8.6064秒
Problem21的答案为31626
  1. %题目21:计算10000以下所有相亲数之和
  2. %标记法
  3. function Output=Problem21(Input)
  4. tic
  5. if nargin==0
  6.     Input=10000;
  7. end
  8. Sum=0;
  9. One=2:Input;
  10. Flag=zeros(1,Input-1);%用标记法
  11. for ii=1:Input-1
  12.      if Flag(ii)==0
  13.          Other=sum(Factor_Num(One(ii)));
  14.          if sum(Factor_Num(Other))==One(ii)&&Other~=One(ii);
  15.              Sum=Sum+One(ii)+Other;
  16.          end
  17.          Flag(ii)=1;
  18.          if isempty(find(One==Other, 1))==0
  19.              Flag(One==Other)=1;
  20.          end
  21.      end
  22. end
  23. Output=Sum;
  24. disp('此代码使用matlab编程')
  25. disp(['Problem21所用时间为',num2str(toc),'秒'])
  26. disp(['Problem21的答案为',num2str(Output)])
  27. end
  28. %% 子程序
  29. %输入一个数得到一个数的真因子的序列(乱序)。
  30. function Output=Factor_Num(Input)
  31. if nargin==0
  32.     Input=10000;
  33. end
  34.     Start=2;
  35.     Stop=Input-1;
  36.     Rank=[];
  37.     while (Stop>Start)
  38.         for ii=Start:Stop
  39.             if mod(Input,ii)==0
  40.                 if Input==ii^2
  41.                     Temp=[Rank,ii];
  42.                 else
  43.                     Temp=[ii,Rank,Input/ii];
  44.                 end
  45.                 Rank=Temp;
  46.                 Start=ii+1;
  47.                 Stop=Input/ii-1;
  48.                 break
  49.             else
  50.                 Start=Start+1;
  51.                 Stop=Stop-1;
  52.             end
  53.         end
  54.     end
  55.     Output=[1,Rank];
  56. end
复制代码
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2017-3-8 23:44:42 | 显示全部楼层
  1. def d(n):
  2.     num = 0
  3.     # 真因子不算自己
  4.     for i in range(1,n):
  5.         if n % i == 0 :
  6.             num += i
  7.     return num

  8. sum_num = 0
  9. print('亲和数为:')
  10. for i in range(1,10000):
  11.     # i等于自己倒数的倒数,还不能等于自己才符合
  12.     if i == d(d(i)) and i != d(i):
  13.         sum_num +=  i
  14.         print(i, end="/")
  15. print('')
  16. print('答案为: ' +str(sum_num))
复制代码
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2017-3-15 11:57:08 | 显示全部楼层
  1. def d(x):
  2.     l=[1]
  3.     for i in range(2,int(x**0.5)+1):
  4.         if not x%i:
  5.             if x==i**2:
  6.                 l.append(i)
  7.             else:l.extend((i,x//i))
  8.     return sum(l)

  9. def Ami(x):
  10.     if d(x)<10000 and d(x)!=x and d(d(x))==x:return 1
  11.     else:return 0

  12. list2=[]
  13. for i in range(10000):
  14.     if Ami(i):
  15.         list2.append(i)
  16. print(sum(list2),'\n',list2)
复制代码

结果:
>>>
31626
[220, 284, 1184, 1210, 2620, 2924, 5020, 5564, 6232, 6368]
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2018-3-16 21:16:44 | 显示全部楼层
  1. #include<stdio.h>
  2. #include<time.h>
  3. int CalculateFactorSum(int x)
  4. {
  5.         int i,sum=0;
  6.         for(i=1;i<x;i++)
  7.         {
  8.                 if(0==x%i)
  9.                 {
  10.                         sum=sum+i;
  11.                 }       
  12.         }
  13.         return sum;
  14. }
  15. int Judge(int x)
  16. {
  17.         int y1,y2;
  18.         y1=CalculateFactorSum(x);
  19.         y2=CalculateFactorSum(y1);
  20.         if(x==y2&&x!=y1)
  21.         {
  22.                 printf("%d\t",x);
  23.                 return 1;
  24.         }
  25.         else
  26.         {
  27.                 return 0;
  28.         }
  29. }
  30. int main()
  31. {
  32.                 int i,sum=0;
  33.                 clock_t start,end;
  34.                 start=clock();
  35.                 for(i=1;i<10000;i++)
  36.                 {
  37.                         if(Judge(i))
  38.                         {
  39.                                         sum=sum+i;
  40.                         }
  41.                 }
  42.                 end=clock();
  43.                 printf("\n%d\n",sum);
  44.                 printf("本次计算用时%f秒\n",(double)(end-start)/CLK_TCK);
  45. }
复制代码
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2018-4-7 23:26:59 | 显示全部楼层
  1. 31626
  2. Time is 6 ms
复制代码
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2018-6-30 16:01:32 From FishC Mobile | 显示全部楼层
#include <iostream>
#include <cmath>
using namespace std;
int sumyz(int num)
{
        int sum=0;
        double a;
        for(int i=1;i<=(int)sqrt(num);++i)
        {
                if(num%i==0)
                {
                        sum+=num/i+i;
                }
        }
        a=(double)num;
        if(a==(int)sqrt(num)*(int)sqrt(num))
        {
                sum-=sqrt(num);
        }
        sum-=num;
        return sum;
}
int main()
{
        bool isqin[10001]={0};
        int num,sum=0;
        for(int i=1;i<=10000;++i)
        {
                if(isqin[i]==1)
                {
                        continue;
                }
                if(i==sumyz(sumyz(i))&&i!=sumyz(i))
                {
                       
                        isqin[i]=1;
                        isqin[sumyz(i)]=1;
                }
        }
        for(int i=1;i<=10000;++i)
        {
                if(isqin[i]==1)
                {
                        sum+=i;
                }
        }
        cout<<sum;
}
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2018-12-27 13:36:13 | 显示全部楼层
[1, 2, 4, 5, 5000, 8, 10, 16, 400, 20, 25, 40, 50, 2500, 200, 2000, 80, 1250, 1000, 625, 500, 250, 125]
我的答案是14111
难道我理解错题目了??
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2019-3-25 14:17:21 | 显示全部楼层
本帖最后由 k往事如烟k 于 2019-3-25 14:39 编辑

  1. def d(n):
  2.     sum = 0
  3.     for i in range(1, n // 2 + 1):
  4.         if n % i == 0:
  5.             sum += i
  6.     return sum

  7. sum = 0
  8. for i in range(1, 10000):
  9.     if i == d(d(i)) and d(i) > i:
  10.         sum += i + d(i)

  11. print(sum)
复制代码
31626
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2019-4-26 23:44:37 | 显示全部楼层
答案和楼上的几位一样,看了人家的代码才明白自己的思路问题出来哪里。
  1. import time
  2. import math

  3. def test1():
  4.     dict1 = {}
  5.     result = 0
  6.     for m in range(1,10001):
  7.         li = []
  8.         num = 0
  9.         for n in range(1,int(math.sqrt(m))+1):
  10.             if m%n == 0:
  11.                 li.append(n)
  12.         if len(li) == 1:
  13.             dict1[m] = li[0]
  14.             continue
  15.         for o in li[1:-1]:
  16.             num = num + o + m//o
  17.         last = li[-1]
  18.         if last**2 == m:
  19.             num += last
  20.         else:
  21.             num = num + last + m//last
  22.         dict1[m] = num+1
  23.    
  24.     print(f'220因子是{dict1[220]},284的因子是{dict1[284]}')
  25.     for i in dict1:
  26.         d_i = dict1[i]
  27.         if d_i == 0:
  28.             continue
  29.         for j in dict1:
  30.             if d_i ==j:
  31.                 d_j = dict1[j]
  32.                 if d_j == 0:
  33.                     continue
  34.                 if d_j == i:
  35.                     if i != j:
  36.                         result = result + i + j
  37.                         dict1[i] = 0
  38.                         dict1[j] = 0


  39.     return result
  40. li = []
  41. start = time.perf_counter()
  42. print(test1())
  43. end = time.perf_counter()
  44. print(end-start)
复制代码
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2019-5-30 11:53:15 | 显示全部楼层
  1. def d(x):
  2.     n = 0
  3.     for i in range(1,x):
  4.         if x%i == 0:
  5.             n += i
  6.     return n

  7. count = 0
  8. for x in range(2,10000):
  9.     if d(x) == x:
  10.         continue
  11.     if d(d(x)) == x:
  12.         count += x
  13. print(count)
复制代码

31626
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2019-6-5 15:20:37 | 显示全部楼层
Result: 31626
用时:3.5559223331028966
  1. import time

  2. def get_sum(num):
  3.     tmp_list = []
  4.     result_list = []
  5.     for num in range(1, num+1):
  6.         tmp_list.append(sum([i for i in range(1, num) if not num % i]))
  7.     for i, j in enumerate(tmp_list):
  8.         if tmp_list[i]-1 <= 10000 and tmp_list[tmp_list[i]-1] == i+1 and i+1 != tmp_list[i]:
  9.             result_list.extend([i+1, tmp_list[i]])
  10.     return sum(set(result_list))

  11. start = time.clock()
  12. print("Result: {} \n用时:{}".format(get_sum(10000), time.clock()-start))
复制代码
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2019-8-6 12:21:03 | 显示全部楼层
本帖最后由 永恒的蓝色梦想 于 2021-2-8 16:26 编辑

31626
  1. #include<iostream>
  2. unsigned i, j, sum = 0, d[30001];



  3. int main() {
  4.     using namespace std;
  5.     ios::sync_with_stdio(false);


  6.     for (i = 1; i <= 15000; i++) {
  7.         for (j = i * 2; j <= 30000; j += i) {
  8.             d[j] += i;
  9.         }
  10.     }

  11.     for (i = 1; i < 10000; i++) {
  12.         j = d[i];

  13.         if (j != i && d[j] == i) {
  14.             sum += i;
  15.         }
  16.     }


  17.     cout << sum << endl;
  18.     return 0;
  19. }
复制代码
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-5-13 15:35:34 | 显示全部楼层
31626
0.031 s
  1. #include <stdio.h>
  2. #include <math.h>
  3. #include <time.h>

  4. int main(void)
  5. {
  6.     clock_t start, finish;
  7.     double duration;
  8.     start = clock();

  9.     int sum = 1;
  10.     int sum2 = 1;
  11.     int sum3 = 0;
  12.     for (int i =  4; i < 10000; ++i) {
  13.         for (int j = 2; j <= sqrt(i); ++j) {
  14.             if (i % j == 0){
  15.                 if (i / j == j)
  16.                     sum += j;
  17.                 else
  18.                     sum += j + i / j;
  19.             }
  20.         }
  21.         for (int j = 2; j <= sqrt(sum); ++j) {
  22.             if (sum % j == 0){
  23.                 if (sum / j == j)
  24.                     sum2 += j;
  25.                 else
  26.                     sum2 += j + sum / j;
  27.             }
  28.         }
  29.         if (i == sum2){
  30.             if (sum != sum2)
  31.                 sum3 += sum2 + i;
  32.         }
  33.         sum = 1;
  34.         sum2 = 1;
  35.     }

  36.     printf("%d\n", sum3 / 2);

  37.     finish = clock();

  38.     duration = (double )(finish - start)/CLOCKS_PER_SEC;

  39.     printf("%.3f s\n", duration);
  40.     return 0;
  41. }
复制代码
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-4-24 22:04

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表