本文已参与[新人创作礼]活动,一起开启掘金创作之路
小插曲
这是初学算法的我
这是加入万人学习社区的我
在此,博主准备分享一个万人学习的社区,这里有许多大佬指引前行,大家互相勉励学习,欢迎大家加入这个社区。博主也是小白,理解大家的困惑,一个人学习太艰难了,不容易走的很远。
万人千题社区 https://bbs.csdn.net/forums/hero?category=0
文章目录
四因数
力扣 1390.四因数 https://leetcode-cn.com/problems/four-divisors/
一.方法一
枚举
我们可以遍历数组 nums 中的每个元素,依次判断这些元素是否恰好有四个因数。对于任一元素 x,我们可以用类似质数判定的方法得到它的因数个数,其本质为:如果整数 x 有因数 y,那么也必有因数 x/y,并且 y 和 x/y 中至少有一个不大于 sqrt(x)。这样我们只需要在 [1, sqrt(x)] 的区间内枚举可能为整数 x 的因数 y,并通过 x/y 得到整数 x 的其它因数。如果x恰有四个因数,将其相加即可。
代码如下
int sumFourDivisors(int* nums, int numsSize) {
int m = 0; //题目要求如果数组中不存在满足题意的整数,则返回 0 ,故此定义。
for (int i = 0; i < numsSize; i++) { //遍历数组
int count = 0; int sum = 0; //注意定义count,sum=0的位置
for (int j = 1; j <= sqrt(nums[i]); j++) {//j属于此范围[1, sqrt(x)]
if (nums[i] % j == 0) {
count++;
sum += j;
if (j * j != nums[i]) { //当相等时,为停止循环的条件
count++; sum += nums[i] / j;
}
}
}if (count == 4) m += sum; //count==4时 m+=sum
}return m;
}
二. 方法二
求一个数n的因子和
(1)对n进行素数分解后,最小素数的为p素因子p的个数为e,那
(2)当n的因子中p的个数为0,因子之和为s(n')。若n的因子中p的个数为k,因子之和
(3)所有的因子之和为
(4)s(n')使用等比数列可化为
<1>分析题目
根据因子的定义,共分两种情况
(1)两个素数的乘积,即x=pq:
``
(2)某个素数的三次幂,即x=p的三次方:
``
<2>源码解析
#define maxn 100001 // 数组上限100001
#define ll long long
bool f[maxn];
int primes[maxn];
void ethPrime() { //以下为埃式筛法
int i;
ll j;
f[0] = f[1] = 1;
primes[0] = 0;
for (i = 2; i < maxn; ++i) {
if (!f[i]) {
primes[++primes[0]] = i;
for (j = (ll)i * i; j < maxn; j += i) {
f[j] = 1;
}
}
}
}
bool isPrime(int x) {
return !f[x];
}
int sumFourDivisors(int* nums, int numsSize) {
int i, j, p, q;
int ans = 0;
ethPrime();
for (i = 0; i < numsSize; ++i) {
for (j = 1; j <= primes[0]; ++j) {
p = primes[j]; //(1)和(2)对称解法求素数
if (nums[i] % p == 0) { //素数的判断
q = nums[i] / p; //(2)
if (isPrime(q) && p != q) {
ans += (p + 1) * (q + 1); // 因子数的第一种情况
}
if (q == (long long)p * p) {
ans += p * p * p + p * p + p + 1; // 因子数的第二种情况
}
break;
}
}
}
return ans;
}