《算法零基础》第12讲:因子和题解

Posted Sauron7i

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了《算法零基础》第12讲:因子和题解相关的知识,希望对你有一定的参考价值。

前言

原文出自:算法零基础100讲

LeetCode 1390.四因数

原题链接:1390.四因数

分析

根据题目要求得出,如果一个数满足有四个因数,那除去 1和数字本身,就剩下两个素数的乘积。所以有以下两种情况:

1.两个素数的乘积,即 num = p*q;
2.某个素数的三次幂, 即 num = p×p×p;

方法

  1. 首先要筛选出题目范围内所有的素数,文章采用的筛选方法为埃氏筛。
  2. 遍历数组,对每个数字num, 在[2, sqrt(num)]范围内的素数进行试除
  3. 如果数字num能够分解为两个素数,或一个素数的三次幂,则使用因子和公式,求出因子和。

因子和公式

出处:英雄哪里出来
专栏:《算法零基础100讲》

如果该数据num可由两个素数相乘得到,即 num = p*q,则因子和公式为:

如果该数据num是由一个素数的三次幂得到,即num = p×p×p,则因子和公式为:

代码

#define maxn 100001
#define ll long long

//全局数组默认初始化为0
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) //遍历传进来的数组
    { 
    	//遍历素数,primes[0]中存放的素数个数            
		for (j = 1; j <= primes[0]; ++j) 
        {       
			p = primes[j];
			if (nums[i] % p == 0)
            {
				q = nums[i] / p;
				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;
}

个人感觉大哥用的方法,是非常聪明,还能帮助我们巩固一下基础知识,非常赞👍。

以上是关于《算法零基础》第12讲:因子和题解的主要内容,如果未能解决你的问题,请参考以下文章

题解《算法零基础100讲》(第10讲) 因子分解和枚举(java版)

《算法零基础》第10讲:因子分解和枚举(部分)

《算法零基础》第9讲:算术基本定理

《算法零基础100例》(第12例) 因子和

题解《算法零基础100讲》(第6讲) 日期算法(java版)

题解《算法零基础100讲》(第16讲) 变量交换算法(java版)