零、写在前面
这是打卡的第十二天,主要内容在
《算法零基础100讲》(第12讲) 因子和https://blog.csdn.net/WhereIsHeroFrom/article/details/120875424
一、主要知识点
一个数n的因子和
对于n我们进行相应的因式分解
那么我们很容易得到n的所有约数是a1取0.....a1,a2取0....a2,a3取0.....a3得到积一共有(a1+1)(a2+1)(a3+1)个结果
那么S(n) = (1 + p^1+p^2 + ... p^a1)(1+q^1+...q^a2)......
每个括号里面分别对应a1+1个,a2+1....个元素,拆开刚好对应所有的约数。
那么S(n)很容易看出来每个括号里都是一个等比数列,所以一共就是
二、课后习题详解
四因子数
思路
题目说了一共包含四个因子,那么只能是
- 两个质因子的乘积
- 是一个质因子的三次方两种情况。
对于质数我们可以用之前学过的线性筛进行筛选,然后就行判定求解。
#define maxn 50001
bool f[maxn];
int primes[maxn];
void ethPrime(){ //
memset(f,1,sizeof(f));
primes[0] =0;
for(int i = 2;i < maxn; ++i){
if(f[i]) primes[++primes[0]] = i;
for(int j = 1;j <= primes[0] && primes[j] * i < maxn;j++){
f[i*primes[j]] = 0;
if(!i % primes[j] )break;
}
}
}
int sumFourDivisors(int* nums, int numsSize){
int ans = 0;
ethPrime();
for(int i = 0;i < numsSize;i++)
for(int j = 1;j<= primes[0]&&primes[j] <nums[i];++j)
if(!(nums[i] % primes[j]))//找到第一个质因子
if(f[nums[i] / primes[j]] && primes[j]*primes[j] != nums[i]){//是否满足第一种情况
ans += (primes[j] +1)*(nums[i] / primes[j] +1);
break;
}
else if((long long )primes[j]*primes[j]*primes[j] == nums[i]){//是否满足第二种情况
ans += (pow(primes[j],4) - 1)/(primes[j] - 1);
break;
}
else break;//不满足两种情况,及时返回
return ans;
}
结果分析
在代码中及时返回减少了一些时间达到了76ms,但是,,,我不满意。。。
思路2
打表yyds,但是我尝试了一下,页面卡死,提交不了???是被制裁了?那不让我打表进去,我让机器进行打表就好了,我用一个数组生成所有的数据,查表就行了。
#define maxn 50001
bool f[maxn];
int primes[maxn];
int siyuanzu[100001] = {0};
void init(){//生成所有的变量对应的值
for(int i = 1;i <= primes[0] && primes[i]*primes[i]*primes[i] < 100001;i++)
siyuanzu[primes[i]*primes[i]*primes[i]] = (pow(primes[i],4) - 1)/(primes[i] - 1);
for(int i = 1;i <= primes[0];i++)
for(int j = 1;i != j && j <= primes[0] && (long long)primes[i]*primes[j] < 100001;j++)
siyuanzu[primes[i]*primes[j]] =(primes[i] + 1)*(primes[j] + 1);
}
void ethPrime(){//埃氏筛
memset(f,1,sizeof(f));
primes[0] = 0;
for(int i = 2;i < maxn;++i){
if(f[i]){
primes[++primes[0]] = i;
for(long long j = (long long)i*i;j < maxn;j+=i)
f[j] = 0;
}
}
}
/*
void ethPrime(){ //欧拉筛
memset(f,1,sizeof(f));
primes[0] =0;
for(int i = 2;i < maxn; ++i){
if(f[i]) primes[++primes[0]] = i;
for(int j = 1;j <= primes[0] && primes[j] * i < maxn;j++){
f[i*primes[j]] = 0;
if(!i % primes[j] )break;
}
}
}*/
int sumFourDivisors(int* nums, int numsSize){
int ans = 0;
ethPrime();
init();
for(int i = 0;i < numsSize;++i){
printf("%d",siyuanzu[nums[i]]);
ans += siyuanzu[nums[i]];
}
return ans;
}
结果分析
那就这样吧
课后总结
linux环境高级编程好高级,高级的我写作业写了300行还没写完┭┮﹏┭┮,写完了过两天写篇文章介绍一下这个高级编程-.-