Problem 12 : Highly divisible triangular number

Problem 12


Highly divisible triangular number

The sequence of triangle numbers is generated by adding the natural numbers. So the 7th triangle number would be 1 + 2 + 3 + 4 + 5 + 6 + 7 = 28. The first ten terms would be:

1, 3, 6, 10, 15, 21, 28, 36, 45, 55, …

Let us list the factors of the first seven triangle numbers:

 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

We can see that 28 is the first triangle number to have over five divisors.

What is the value of the first triangle number to have over five hundred divisors?


高度可约的三角形数

三角形数数列是通过逐个加上自然数来生成的。例如,第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个约数的三角形数是多少?

题目解答

    朴素解法:暴力枚举
   优化算法:利用线性筛法计算计算每个数字的因子个数

    
题目代码

#include <stdio.h>
#include <inttypes.h>
#include <stdlib.h>
#define N 2000000
int32_t prime[N + 5] = {0};
int32_t factor[N + 5] = {0};
void init(){
    for (int i = 2; i < N; i++){
        if (!prime[i]){
            prime[++prime[0]] = i;
            factor[i] = 2;
        }
        for (int j = 1; j <= prime[0]; j++){
            if (i * prime[j] > N) break;
            prime[i * prime[j]] = 1;
            if(i % prime[j] == 0){
                int cnt = 0;
                int temp = i;
                while(temp % prime[j] == 0){
                    temp /= prime[j];
                    ++cnt;
                }
                factor[i * prime[j]] = factor[i] / (cnt + 1) * (cnt + 2);
                break;
            }else{
                factor[i * prime[j]] = factor[i] * factor[prime[j]];
            }
        }
    }
}
int main() {
    init();
    for (int i=1;;i++){
        int temp;
        if(i & 1){
            temp = factor[(i+1)/2] * factor[i];
        }else{
            temp = factor[i+1] * factor[i/2];
        }
        if(temp > 500){
            printf("%d\n",i*(i+1)/2);
            break;
        }
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/Ruger008/article/details/80375109