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是第一个约数数量超过五的三角形数。
第一个约数数量超过五百的三角形数是多少?
这个题主要求的是一个数的约数,一个质数的约数等于1和他本身,那么一个合数呢这就是这题的关键所在:
一个合数等于他的质因子的幂次相乘的来的,你通过我之前的线性筛就可以发现这个问题线性筛,比如
通过这个性质可以去求得合数的因子,继续往下看,现在把36作为一个例子
你会通过发现从上往下可以得到
这就是一个36的所有因子,你可以发现他用他质因子的幂次可以得到所有的因子,但是怎么去计算呢,不可能一步一步算出来吧;
现在你把2^2和3^2看为一个集合,他们可以得到的因子是不是笛卡尔积?
所以最终
所以不难发现,一个合数的因子个数等于他质因子的幂加一相乘的来的
所以得到公式
ai 表示质因子的幂次,n代表第n个质因数
现在假如A 和 B互质,求
AB互质说明什么,说明他们没有共同的质因子比如3 和 5
所以他们之间的F(N)是互不影响的所以
得到了这些性质,可能还是不会如何去编写代码,如果你对我之前线性筛的方法理解并且自己实现了,那对于下面的代码你肯定能看懂
#include <stdio.h> #define MAX_N 20000 int prime[MAX_N + 5]; int f[MAX_N + 5];//因子个数 int cnt[MAX_N + 5];//当前数最小质因次的幂次 int main() { f[1] = 1; for (int i = 2; 2 * i <= MAX_N; i++) { if (!prime[i]) { prime[++prime[0]] = i; f[i] = 2; cnt[i] = 1; } for (int j = 1; i * prime[j] <= MAX_N; j++) { prime[i * prime[j]] = 1; if (i % prime[j] == 0) { f[i * prime[j]] = f[i] / (cnt[i] + 1) * (cnt[i] + 2);//因为prime[j]为i的最小质因子,根据刚才求合数的因子的公式,你先把之前prime[j]乘上的,然后在加一再乘上就可以得到对应的数的因子数了; cnt[i * prime[j]] = cnt[i] + 1; break; } else { cnt[i * prime[j]] = 1;//因为prime[j] 为他的最小质因子,所以对于最小质因子的幂次为1次 f[i * prime[j]] = f[i] * f[prime[j]];//这里用了两个数互质等于他们因子数相乘 } } } for (int i = 1; i < 100; i++) printf("f[%d] = %d\n", i, f[i]); //得到每个数因子个数后可以来求当前题目的答案了 int n = 1, fns = 0; // 三角形数 = n * (n + 1) / 2;很容易知道n和n + 1是互质的所以三角形数的质数可以用下面的方式表示 while (1) { if (n & 1) fns = f[n] * f[(n + 1) / 2];// n为奇数 n + 1就为偶数 else fns = f[n / 2] * f[n + 1]; if (fns > 500) break; n++; } printf("%d %d\n", n * (n + 1) / 2, fns); return 0; }
最终答案:76576500 他的因子个数为576