《算法零基础100讲》(第10讲) 因子分解和枚举
【摘要】 因子分解和枚举
零、写在前面
这是《算法零基础100讲》 专栏打卡学习的第十天了,虽然打卡人数看起来越来越少,但是 第一天打卡刷题 的人数与日俱增,源源不断的新生代涌入 万人千题 计划,目前已破千人,成功的路上永远不会孤独,与神同行,坚持下去,爆发只在一瞬之间。
一、概念定义
根据算术基本定理 和 素因子筛选,我们可以对一个数进行素因子的试除,例如:当一个数
存在一个素因子
的时候,我们可以将它变成
,然后再判断是否能被
整除,直到除尽所有
时,再去判断
、
、
等所有
内的素因子。
例如:252 在进行素因子分解后变成
。
首先准备一个结构体factor
,用来表示它的素因子是什么,以及该素因子的个数。
struct factor {
int prime, count;
factor() :prime(0), count(0) {}
factor(int p, int c) : prime(p), count(c) {}
void print() {
printf("(%d, %d)\n", prime, count);
}
};
然后,利用一个素因子分解的接口Factorization(int n, vector <factor>& ans)
来实现枚举素因子的分解。即对于
的情况,函数计算完毕后,ans
中存的结果是:[ (2,2), (3,2), (7,1) ]
void Factorization(int n, vector <factor>& ans) {
ans.clear();
if(n == 1) {
return ; // (1)
}
// 素数试除
for(int i = 1; i <= primes[0]; i++) { // (2)
if(n % primes[i] == 0) { // (3)
factor f(primes[i], 0); // (4)
while( !(n % primes[i]) ) { // (5)
n /= primes[i];
f.count ++;
}
ans.push_back(f); // (6)
}
if(n == 1) {
return ;
}
}
ans.push_back( factor(n, 1) ); // (7)
}
- 1 不需要素因子分解。
-
primes[0]
代表在进行素数筛选时,素数的个数,素数筛选的内容,参考:《算法零基础100讲》(第8讲) 素数筛选。 - 对每一个素数进行试除;
- 调用构造函数;
-
如果存在
prime[i]
这个素因子,则将它除掉,并且个数计数自增; - 记录一个素因子信息;
- 所有素数都除不尽,说明它本身是一个素数;
二、题目描述
给定一个整数 ,请找出同时满足下面全部要求的两个整数:
1)两数乘积等于 或 ;
2)以绝对差进行度量,两数大小最接近;
三、算法详解
首先,枚举 和 两种情况,分别对它们进行 的试除,计算绝对值,去绝对值小的整数对计入答案。
四、源码剖析
int* closestDivisors(int num, int* returnSize){
int *ret = (int *)malloc( 2 * sizeof(int) ); // (1)
int n, i, sub = -1;
for (n = num+1; n <= num+2; ++n) { // (2)
for(i = 1; i * i <= n; ++i) {
if(n % i) // (3)
continue;
if ( sub == -1 || abs(n/i - i) < sub ) { // (4)
sub = abs(n/i - i);
ret[0] = n/i;
ret[1] = i;
}
}
}
*returnSize = 2; // (5)
return ret;
}
- 申请一个结果数组;
- 枚举 和 ;
- 不是因子的直接跳过;
- 根据因子 和 的绝对值,取小的记录最优值;
-
*returnSize
作为返回值返回;
五、推荐专栏
六、习题练习
【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱:
cloudbbs@huaweicloud.com
- 点赞
- 收藏
- 关注作者
评论(0)