鱼C论坛

 找回密码
 立即注册
12
返回列表 发新帖
楼主: 欧拉计划

题目12:第一个拥有超过500个约数的三角形数是多少?

[复制链接]
发表于 2018-9-4 15:12:34 | 显示全部楼层
python3 结果是:76576500
时间:0.970447 s
  1. import time

  2. start = time.clock()
  3. def get_divisors_num(n, prime):
  4.     num = 1
  5.     count = 1
  6.     while (n > 1):
  7.         for p in prime:
  8.             while(n % p == 0):
  9.                 count += 1
  10.                 n = n // p
  11.             num *= count
  12.             count = 1
  13.             if n == 1:
  14.                 break
  15.     return num


  16. def get_primes(number):
  17.     # '筛法找出所有质数,并求和'
  18.     list_primes = [True] * (number + 1)
  19.     list_primes[0] = False
  20.     list_primes[1] = False
  21.     for i in range(2, number):
  22.         if list_primes[i]:
  23.             for j in range(i ** 2, number, i):
  24.                 list_primes[j] = False
  25.     list_result = []
  26.     for k in range(2, number):
  27.         if list_primes[k]:
  28.             list_result.append(k)
  29.     return list_result


  30. prime = get_primes(100000)
  31. n = 1
  32. while 1:
  33.     n += 1
  34.     s = n * (n - 1) // 2
  35.     if get_divisors_num(s, prime) > 500:
  36.         break
  37. print(s)

  38. end = time.clock()
  39. print("read:%f s" % (end - start))
复制代码
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2018-10-19 15:34:57 | 显示全部楼层
  1. from math import sqrt
  2. def count(n):
  3.     t = 0
  4.     for i in range(1, n+1):
  5.         t += i
  6.     return t

  7. for r in range(10000000):
  8.     s = count(r)
  9.     result = []
  10.     for i in range(1, int(sqrt(s))+1):
  11.         if s%i == 0:
  12.             result.append(i)
  13.     if len(result) > 250:
  14.         print(s)
  15.         print(len(result))
  16.         break
复制代码


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

使用道具 举报

发表于 2019-4-25 16:17:22 | 显示全部楼层
  1. import time
  2. import math
  3. import functools

  4. def test1():
  5.     num = 1
  6.     count = 0  #约数个数
  7.     li = []
  8.     while len(li) < 500:
  9.         count = 0
  10.         li = []
  11.         if num%2 == 0:
  12.             sjx_num = (num+1)*(num//2)
  13.             if sjx_num%2 == 0:
  14.                 i = 1
  15.                 j = 4
  16.                 while i < j:
  17.                     if sjx_num%i == 0:
  18.                         j = sjx_num//i
  19.                         li.extend([i,j])
  20.                     i += 1
  21.                            
  22.             else:
  23.                 i = 1
  24.                 j = 4
  25.                 while i < j:
  26.                     if sjx_num%i == 0:
  27.                         j = sjx_num//i
  28.                         li.extend([i,j])
  29.                     i += 2
  30.                            
  31.         else:
  32.             sjx_num = num*(num//2) + num
  33.             if sjx_num%2 == 0:
  34.                 i = 1
  35.                 j = 4
  36.                 while i < j:
  37.                     if sjx_num%i == 0:
  38.                         j = sjx_num//i
  39.                         li.extend([i,j])
  40.                     i += 1
  41.         
  42.             else:
  43.                 i = 1
  44.                 j = 4
  45.                 while i < j:
  46.                     if sjx_num%i == 0:
  47.                         j = sjx_num//i
  48.                         li.extend([i,j])
  49.                     i += 2
  50.                            

  51.         num += 1
  52.         

  53.    
  54.     return sjx_num,num-1

  55. start = time.perf_counter()

  56. print(test1())
  57. end = time.perf_counter()
  58. print(end-start)
复制代码
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2019-8-3 19:45:12 | 显示全部楼层
本帖最后由 永恒的蓝色梦想 于 2020-5-9 17:31 编辑

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

使用道具 举报

发表于 2019-10-12 11:27:05 | 显示全部楼层
#include <stdio.h>
void main(){
        //高度可约的三角形数
        //三角形数数列是通过逐个加上自然数来生成的。
        //例如,第7个三角形数是 1 + 2 + 3 + 4 + 5 + 6 + 7 = 28。三角形数数列的前十项分别是:
        //1, 3, 6, 10, 15, 21, 28, 36, 45, 55, …
        //让我们列举出前七个三角形数的所有约数:
        //1: 1        // 3: 1,3        // 6: 1,2,3,6        //10: 1,2,5,10        //15: 1,3,5,15        //21: 1,3,7,21        //28: 1,2,4,7,14,28
        //我们可以看出,28是第一个拥有超过5个约数的三角形数。
        //第一个拥有超过500个约数的三角形数是多少?
       
        int i=1,count=0;//i:从 1循环到无穷的数,count:记录三角形数有几个因数
        long sum=0; //sum:i的和(三角形数)
        while(1){
                sum+=i;//计算出三角形数
                int j;
                for(j=1;j<=sum;j++){//从 1到 这个三角形数的循环
                        if(sum%j==0){//找能整除的数的个数(因数个数)
                                count++;//如果能整除说明是因数,count+1
                        }
                }
                printf("三角形数:%d,有%d个因数\n",sum,count);//看count到几了
               
                if(count>5){//大于5,就输出这个三角形数 ,跳出 while循环 (大于500同理)
                        printf("超过5个约数的三角形数:%d",sum);
                        break;
                }else{//count记录完上一个三角形数后,要清零记录下一个
                        count=0;
                }       
                i++;
        }
}
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-3-12 21:15:25 | 显示全部楼层
发现与素数都离不开关系
  1. void getApproximation(int *answer, int flag, int stop)
  2. {
  3.     int array[flag] = {0};
  4.     int temp[flag] = {0};
  5.     array[0] = 2;
  6.     int i = 1;

  7.     int j = 3;
  8.     int k = 0;

  9.     bool yes = 1;
  10.     while(true)
  11.     {
  12.         if(i == flag)
  13.         {
  14.             break;
  15.         }
  16.         else
  17.         {
  18.             k = 0;
  19.             while( k < i)
  20.             {
  21.                 if(j % array[k] == 0)
  22.                 {
  23.                     yes = 0;
  24.                     break;
  25.                 }
  26.                 k++;
  27.             }
  28.             if(yes)
  29.             {
  30.                 array[i++] = j;
  31.             }
  32.         }
  33.         j += 2;
  34.         yes = 1;
  35.     }

  36.     j = 1;
  37.     while(true)
  38.     {
  39.         j++;
  40.         yes = 1;
  41.         *answer = 1;
  42.         // construct trigle
  43.         int value = 0;
  44.         int sum = 0;
  45.         sum = (j*(j+1))/2;
  46.         value = sum;
  47.         //printf("temp:1->%d = %d\t", j, value);
  48.         // calculate this number approximation

  49.         k = 0;
  50.         while(k < i)
  51.         {
  52.             // judge is union
  53.             while(sum % array[k] == 0)
  54.             {
  55.                 temp[array[k]-1] += 1;
  56.                 sum /= array[k];
  57.                 yes = 0;
  58.             }
  59.             // put next prime to compare
  60.             if(sum > array[k])
  61.             {
  62.                 k++;
  63.             }else
  64.             {
  65.                 break;
  66.             }
  67.         }
  68.         if(yes)
  69.         {
  70.             temp[sum-1] = 1;
  71.         }
  72.         for(k = 0; k < array[k]; k++)
  73.         {
  74.             //printf("%d\n", temp[k]);
  75.             if(temp[k] > 0)
  76.             {
  77.                 *answer *= (temp[k] + 1);
  78.             }
  79.             temp[k] = 0;
  80.         }
  81.         //printf("choice:%d\n", *answer);
  82.         //break;
  83.         if(*answer >= stop)
  84.         {
  85.             printf("over:%d\n", value);
  86.             break;
  87.         }
  88.     }
  89. }
  90. int main(int argc, char *argv[])
  91. {
  92.     //ElementType  ret;
  93.     int ret;
  94.     getApproximation(&ret, 100000, 500);
  95.     printf("answer:%d\n", ret);
  96.     //test();
  97.     return 0;
  98. }
复制代码
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-3-13 23:57:36 | 显示全部楼层
想复杂了,简单的
  1. void getApproximationImprove(ElementType *answer, int flag)
  2. {
  3.     ElementType start = 1;
  4.     ElementType sum = 0;
  5.     ElementType numTemp;
  6.     int count = 0;
  7.     while(true){
  8.         count = 0;
  9.         sum = start*(start+1)/2;
  10.         for(numTemp = 1; numTemp <= (ElementType) pow(sum, 0.5);numTemp++)
  11.         {
  12.             if(sum % numTemp == 0) count++;
  13.         }
  14.         *answer = sum;
  15.         if(2*count >= flag){
  16.             printf("%d\t%lld\t",2*count,start);
  17.             return;
  18.         }
  19.         start++;
  20.     }
  21. }

  22. int main(int argc, char *argv[]){
  23.     //ElementType  ret;
  24.     ElementType ret = -1;
  25.     getApproximationImprove(&ret,500);
  26.     printf("answer:%lld\n", ret);
  27.     return 0;
  28. }
复制代码
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-4-19 18:50:30 | 显示全部楼层
本帖最后由 永恒的蓝色梦想 于 2020-5-9 18:14 编辑

C++ 251ms
  1. #include<iostream>
  2. #include<cmath>
  3. using namespace std;


  4. int main() {
  5.     int i, j = 1, count = 0, k;
  6.     double root;

  7.     for (i = 1;; i += ++j) {
  8.         root = sqrt(i);
  9.         count = 0;

  10.         for (k = 2; k < root; ++k) {
  11.             if (!(i % k)) {
  12.                 ++count;
  13.             }
  14.         }

  15.         if (count > (fmod(root, 1) ? 249 : 250)) {
  16.             cout << i << endl;
  17.             return 0;
  18.         }
  19.     }
  20. }
复制代码
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-5-9 16:37:07 | 显示全部楼层
本帖最后由 leon0149 于 2020-5-14 22:03 编辑

76576500
0.105 s
  1. #include <stdio.h>
  2. #include <time.h>

  3. int main(void) {
  4.     int num = 1;
  5.     int i = 2;
  6.     int cnt = 0;

  7.     clock_t start, finish;
  8.     double duration;
  9.     start = clock();

  10.     while (cnt < 500) {
  11.         cnt = 0;
  12.         num += i;
  13.         for (int j = 1; j *j <= num; ++j) {
  14.             if (num % j == 0) {
  15.                 if (j * j == num) {
  16.                     cnt++;
  17.                 } else {
  18.                     cnt += 2;
  19.                 }
  20.             }
  21.         }
  22.         i++;
  23.     }

  24.     printf("%d\n", num);

  25.     finish = clock();
  26.     duration = (double)(finish - start)/CLOCKS_PER_SEC;
  27.     printf("%.3f s", duration);

  28.     return 0;
  29. }
复制代码
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-10-6 15:59:53 | 显示全部楼层
  1. '''三角形数序列是由对自然数的连加构造而成的。所以第七个三角形数是 1 + 2 + 3 + 4 + 5 + 6 + 7 = 28. 那么三角形数序列中的前十个是:
  2. 1, 3, 6, 10, 15, 21, 28, 36, 45, 55, ...
  3. 下面我们列出前七个三角形数的约数:
  4. 1: 1
  5. 3: 1,3
  6. 6: 1,2,3,6
  7. 10: 1,2,5,10
  8. 15: 1,3,5,15
  9. 21: 1,3,7,21
  10. 28: 1,2,4,7,14,28
  11. 可以看出 28 是第一个拥有超过 5 个约数的三角形数。
  12. 那么第一个拥有超过 500 个约数的三角形数是多少?'''

  13. def trinum(num_of_divisors):
  14.     end_num = 1
  15.     sum = 0
  16.     Num_of_divisors = 0

  17.     while Num_of_divisors < num_of_divisors:
  18.         Num_of_divisors = 0
  19.         sum += end_num

  20.         if math.sqrt(sum) == int(math.sqrt(sum)):
  21.             Num_of_divisors += 1

  22.         for divisors in range(1,int(math.sqrt(sum))):
  23.             if sum % divisors == 0:
  24.                 Num_of_divisors += 2

  25.         end_num += 1

  26.     print("第一个拥有超过500个约数的三角形数是: %d" %sum)
  27.     print("一共有%d个约数" %Num_of_divisors)

  28. start_trinum = time.time()
  29. trinum(500)
  30. time_trinum = time.time() - start_trinum
  31. print("%f秒" %time_trinum)
复制代码



第一个拥有超过500个约数的三角形数是: 76576500
一共有576个约数
3.206136秒
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-11-5 18:33:47 | 显示全部楼层
import math as m
import datetime as dt


def div():
    record = []
    count = 0
    n = 0
    while 1 :
        count += 1
        n += count
        for each in range(1, int(m.sqrt(n))+ 1):
            if n % each == 0:
                record.append(each)
        if len(record) > 250:
            print (n)
            print (count)
            break
        record = []
start = dt.datetime.now()
div()
end = dt.datetime.now()
print ("用时" , end - start)
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2021-3-6 21:50:34 | 显示全部楼层
  1. #include <stdio.h>
  2. #include <math.h>

  3. main()
  4. {
  5.         int i, j = 2, k, num = 1, count = 0;
  6.         while (1)
  7.         {
  8.                 num += j;
  9.                 j++;
  10.                 k = sqrt(num);
  11.                 for (i = 2; i <= k; i++)
  12.                 {
  13.                         if (num % i == 0)
  14.                         {
  15.                                 if (i * i == num)
  16.                                 {
  17.                                         count++;
  18.                                 }
  19.                                 else
  20.                                 {
  21.                                         count += 2;
  22.                                 }
  23.                         }
  24.                 }
  25.                 if (count + 2 > 500)
  26.                 {
  27.                         break;
  28.                 }
  29.                 count = 0;
  30.         }
  31.         printf("第一个超过500个约数的三角数是:%d\n", num);
  32. }
复制代码



若有错误,望大佬纠正!
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2021-8-12 23:41:36 | 显示全部楼层
本帖最后由 卢本伟牛逼 于 2021-8-12 23:47 编辑
  1. #include <stdio.h>
  2. #include <math.h>

  3. int count = 0;

  4. int count_fact(int value)
  5. {
  6.         int i;
  7.         int flag = 0;
  8.         for(i=1;i<sqrt(value) + 1;i++)
  9.         {
  10.                 count += 1;
  11.                 if (value%i==0) flag += 2;
  12.         }
  13.         return flag;
  14. }

  15. int count_fact2(int value)
  16. {
  17.         int i;
  18.         int result = 1;
  19.         int flag;
  20.         if (value <= 2) return 0;
  21.         for(i=2; i<=value; i++){
  22.                 flag = 0;
  23.                 count += 1;
  24.                 while(value % i == 0){
  25.                         flag += 1;
  26.                         value /= i;
  27.                 }
  28.                 if (flag!=0){
  29.                         result *= (flag + 1);
  30.                 }
  31.         }
  32.         return (result == 1)?0:result;
  33. }

  34. int main(void)
  35. {
  36.         int i=1;

  37.         while(count_fact2((i+1)*i/2) < 500) i++;

  38.         printf("result = %d\n", (i+1)*i/2);
  39.         printf("count = %d\n", count);

  40.         return 0;
  41. }
  42. //count_fact result = 76576500
  43. //count_fact count  = 54157266

  44. //count_fact2 result = 76576500
  45. //count_fact2 count  = 26736502
复制代码
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2021-10-29 10:06:17 | 显示全部楼层
  1. #include<stdio.h>

  2. int main(void)
  3. {
  4.         unsigned int sum = 0,num = 0;
  5.        
  6.         for(int i = 1;;i++)
  7.         {
  8.                 sum += i;
  9.                 for(int j = 1;j <= num ;j++)
  10.                 {
  11.                         if(num % j == 0)
  12.                         {
  13.                                 num++;       
  14.                         }
  15.                 }
  16.                 if(num >= 500)               
  17.                 {
  18.                         break;                       
  19.                 }       
  20.         }
  21.        
  22.         printf("%d",sum);
  23.        
  24.         return 0;
  25. }
复制代码
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2021-11-20 16:06:47 | 显示全部楼层
0.2s

  1. #include <stdio.h>

  2. int main(void)
  3. {
  4.         long res = 0;
  5.         long i = 1,j,temp;
  6.         int count = 0;
  7.        
  8.         while (1)
  9.         {
  10.                 res += i;
  11.                 i++;
  12.                 for(j = 1;j < res;j++)
  13.                 {
  14.                         temp = res/j;
  15.                         if (temp < j)
  16.                                 break;
  17.                         if (temp * j == res)
  18.                                 count += 2;
  19.                 }
  20.                 if (count >= 500)
  21.                 {
  22.                         printf("%ld\n",res);
  23.                         return 0;
  24.                 }
  25.                 count = 0;
  26.         }
  27. }
复制代码
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2022-2-24 00:15:31 | 显示全部楼层
  1. package main

  2. import (
  3.         "fmt"
  4.         "time"
  5. )

  6. //题目:
  7. //
  8. //三角形数序列是由对自然数的连加构造而成的。所以第七个三角形数是 1 + 2 + 3 + 4 + 5 + 6 + 7 = 28. 那么三角形数序列中的前十个是:
  9. //
  10. //1, 3, 6, 10, 15, 21, 28, 36, 45, 55, ...
  11. //
  12. //下面我们列出前七个三角形数的约数:
  13. //
  14. //1: 1
  15. //3: 1,3
  16. //6: 1,2,3,6
  17. //10: 1,2,5,10
  18. //15: 1,3,5,15
  19. //21: 1,3,7,21
  20. //28: 1,2,4,7,14,28
  21. //可以看出 28 是第一个拥有超过 5 个约数的三角形数。
  22. //
  23. //那么第一个拥有超过 500 个约数的三角形数是多少?

  24. func yueshu(a int32) int32 {
  25.         n := make(map[int32]int32)
  26.         for {
  27.                 if a > 1 {
  28.                         var i int32
  29.                         for i = 2; i <= a; i++ {
  30.                                 if a%i == 0 {
  31.                                         n[i]++
  32.                                         a /= i
  33.                                         break
  34.                                 }
  35.                         }
  36.                 } else {
  37.                         res := int32(1)
  38.                         for _, value := range n {
  39.                                 res *= (value + 1)
  40.                         }
  41.                         return res
  42.                 }

  43.         }
  44. }

  45. func triangle(n int32) int32 {
  46.         return (1 + n) * n / 2
  47. }

  48. func main() {
  49.         t := time.Now()
  50.         var i int32 = 1
  51.         for {
  52.                 if yueshu(triangle(i)) > 500 {
  53.                         fmt.Println(triangle(i))
  54.                         break
  55.                 }
  56.                 i++
  57.         }
  58.         tt := time.Now()
  59.         fmt.Println("耗时:", (tt.Nanosecond()-t.Nanosecond())/1e6, "ms")
  60. }
复制代码

输出:
  1. GOROOT=C:\Program Files\Go #gosetup
  2. GOPATH=C:\Users\Administrator\go #gosetup
  3. "C:\Program Files\Go\bin\go.exe" build -o C:\Users\Administrator\AppData\Local\Temp\GoLand\___go_build_Euler12_go.exe C:\Users\Administrator\Documents\GoProject\src\Euler12.go #gosetup
  4. C:\Users\Administrator\AppData\Local\Temp\GoLand\___go_build_Euler12_go.exe
  5. 76576500
  6. 耗时: 42 ms

  7. 进程 已完成,退出代码为 0
复制代码
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2022-2-24 00:17:08 | 显示全部楼层
  1. package main

  2. import (
  3.         "fmt"
  4.         "time"
  5. )

  6. //题目:
  7. //
  8. //三角形数序列是由对自然数的连加构造而成的。所以第七个三角形数是 1 + 2 + 3 + 4 + 5 + 6 + 7 = 28. 那么三角形数序列中的前十个是:
  9. //
  10. //1, 3, 6, 10, 15, 21, 28, 36, 45, 55, ...
  11. //
  12. //下面我们列出前七个三角形数的约数:
  13. //
  14. //1: 1
  15. //3: 1,3
  16. //6: 1,2,3,6
  17. //10: 1,2,5,10
  18. //15: 1,3,5,15
  19. //21: 1,3,7,21
  20. //28: 1,2,4,7,14,28
  21. //可以看出 28 是第一个拥有超过 5 个约数的三角形数。
  22. //
  23. //那么第一个拥有超过 500 个约数的三角形数是多少?

  24. func yueshu(a int32) int32 {
  25.         n := make(map[int32]int32)
  26.         for {
  27.                 if a > 1 {
  28.                         var i int32
  29.                         for i = 2; i <= a; i++ {
  30.                                 if a%i == 0 {
  31.                                         n[i]++
  32.                                         a /= i
  33.                                         break
  34.                                 }
  35.                         }
  36.                 } else {
  37.                         res := int32(1)
  38.                         for _, value := range n {
  39.                                 res *= (value + 1)
  40.                         }
  41.                         return res
  42.                 }

  43.         }
  44. }

  45. func triangle(n int32) int32 {
  46.         return (1 + n) * n / 2
  47. }

  48. func main() {
  49.         t := time.Now()
  50.         var i int32 = 1
  51.         for {
  52.                 if yueshu(triangle(i)) > 500 {
  53.                         fmt.Println(triangle(i))
  54.                         break
  55.                 }
  56.                 i++
  57.         }
  58.         tt := time.Now()
  59.         fmt.Println("耗时:", (tt.Nanosecond()-t.Nanosecond())/1e6, "ms")
  60. }
复制代码

输出:
76576500
耗时: 42 ms
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2022-8-9 21:09:15 | 显示全部楼层
本帖最后由 Asss-whom 于 2022-8-9 21:17 编辑
  1. use primes::factors_uniq;

  2. pub fn run() -> Result<(), Box<dyn std::error::Error>> {
  3.     for i in 1.. {
  4.         let num = i * (i + 1) / 2;
  5.         let f = factor(num);
  6.         if f > 500 {
  7.             println!("num = {num}, factors = {f}");
  8.             break;
  9.         }
  10.     }
  11.     Ok(())
  12. }

  13. fn factor(num: u64) -> i32 {
  14.     let f = factors_uniq(num);
  15.     f.into_iter()
  16.         .map(|i| {
  17.             let mut n = num;
  18.             let mut count = 0;
  19.             while n % i == 0 {
  20.                 n = n / i;
  21.                 count += 1
  22.             }
  23.             count
  24.         })
  25.         .fold(1, |acc, x| acc * (x + 1))
  26. }
复制代码

[Project Euler 12]
num = 76576500, factors = 576
[Task finished in 5ms]
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2022-12-19 19:00:19 | 显示全部楼层
本帖最后由 TLM 于 2022-12-19 19:02 编辑

## python
  1. import time
  2. tt=time.time()
  3. # an=n(n+1)/2
  4. # 这个算法的时间复杂度应该是O(nlog(n)),其中n是第n个数,也就是n=O(an**0.5)
  5. # 数学能力有限,不知道和目标数据之间的联系
  6. # 通过列表,获得所有小于等于n+1的数的约数个数
  7. def getNlist(n):
  8.     # 时间复杂度为O(nlog(n))这个是测试的,没计算
  9.     nlist=[0 for i in range(n)]
  10.     for i in range(1,int(n**0.5)+1):
  11.         for j in range(i,n+1):
  12.             if i*j<=n:
  13.                 if i==j:# i为其约数
  14.                     nlist[i*j-1]=nlist[i*j-1]+1
  15.                 else:# i,j都是其约数
  16.                     nlist[i*j-1]=nlist[i*j-1]+2
  17.             else:
  18.                 break
  19.     return nlist

  20. def getminn(nlist,mubiao):
  21.     # O(n)
  22.     for i in range(len(nlist)-1):
  23.         if i%2==1:
  24.             # an=n(n+1)/2,拆成两个n和(n+1)/2这样的结构,最大公约数为1,只有一个相同的约数
  25.             # 排列组合形成an的约数。这是整个算法中最精髓的
  26.             if nlist[(i+1)//2-1]*nlist[i+1]>=mubiao:
  27.                 return False,i+1
  28.         else:
  29.             if nlist[i]*nlist[(i+2)//2-1]>=mubiao:
  30.                 return False,i+1
  31.     return True,0
  32. # 目标值
  33. mubiao=500
  34. n=mubiao
  35. data=(True,0)
  36. while data[0]:
  37.     nlist=getNlist(n)
  38.     data=getminn(nlist,mubiao)
  39.     # print(n)
  40.     # print(nlist)
  41.     # 找不到就放大列表,倍率放大寻找更快
  42.     n=n*2
  43. print(data[1])# 第几个
  44. print(data[1]*(data[1]+1)/2)# 三角数
  45. print(time.time()-tt)
复制代码

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

使用道具 举报

发表于 2023-7-27 17:21:06 | 显示全部楼层
本帖最后由 QLYYLQ 于 2023-7-27 17:33 编辑
  1. #include<stdlib.h>
  2. #include<stdio.h>
  3. #include<stdbool.h>
  4. #include<time.h>
  5. #define NUMBER 200
  6. bool a[NUMBER]={1,1,0}/*当下标对应的数组元素为0的时候,下标是素数*/;
  7. int b[35] = {2,0};/*储存素数*/
  8. void sushu(bool a[], int b[])
  9. {
  10.     int i=2;
  11.     int j=1;
  12.     while(i<NUMBER)
  13.     {
  14.         int i1 = 2*i;
  15.         for(;i1<NUMBER;i1+=i) a[i1]=1;
  16.         i++;
  17.         while(i<NUMBER && a[i]==1) i++;
  18.         b[j]=i;
  19.         j++;
  20.     }
  21. }
  22. int sum(int i)
  23. {
  24.     return (i*(i+1))/2;
  25. }
  26. int jieda(int sum1,int b[])
  27. {
  28.     /*分解质因数*/
  29.     int c[35]={0};
  30.     for(int i=0;i<35;i++)
  31.     {
  32.         while(sum1%b[i]==0)
  33.         {
  34.             c[i]+=1;
  35.             sum1/=b[i];
  36.         }
  37.     }
  38.     /*计算因数个数*/
  39.     int j=0;
  40.     int answer =1;
  41.     while(j<35)
  42.     {
  43.         if(c[j] != 0) answer*=(c[j]+1);
  44.         j++;

  45.     }
  46.     return (answer);
  47. }
  48. int main()
  49. {
  50.     clock_t finish,start;
  51.     start=clock();
  52.     sushu(a,b);
  53.     for(int i =100;i<20000;i++)
  54.     {
  55.         if(jieda(sum(i),b)>=500)
  56.         {
  57.             printf("%d\n",sum(i));
  58.             break;
  59.         }
  60.     }
  61.     finish=clock();
  62.     double duration= (double)(finish - start)/CLOCKS_PER_SEC;
  63.     printf("%.3f",duration);
  64.     system("pause");
  65.     return 0;

  66. }

复制代码

时间是0.06s

这是用C语言写的
首先是用一个欧拉筛来筛选出来需要的素数,再通过质因数来计算因数个数
我的理解是这样的:一个数可以被分解成一连串的素数相乘,那么它的所有因数就是通过质因数不同组合后相乘得到的,比如:24=2*2*2*3,那么24的因数就是1,24; 3,8; 4,6; 2,14;其实都是2,2,2,3的不同组合,比如这里是2的三次方,那么我们就应该有四种选择(不选,选一个,选两个...)来组成一个因数,同理三也是,所以24的因数个数就是(3+1)*(1+1)=8个
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

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

本版积分规则

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

GMT+8, 2024-4-20 05:13

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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