目录
1 分解质因数
#include <bits/stdc++.h>
using namespace std;
int num,temp;
int main()
{
scanf("%d",&num);
temp=num;//保护
for(int i=2;i<=temp;i++)
{
while(num%i==0)
{
printf("%d ",i);
num/=i;
}
}
return 0;
}
说明:这里不需要担心没有筛选质数的问题,因为是从小到大循环,不可能存在分解出合数的情况(例如:2第一个循环,所有2的倍数都已经被筛选掉了,后续循环不可能再有2的倍数被num整除)
2 打印质数表
2.1 O(n^2)算法(暴力法)
两层循环,第一层循环i遍历大于等于2的所有数,第二层循环遍历大于1小于i的所有数j,判断i%j!=0一直成立,则该数为质数
这种方法虽然思路简单,但时间复杂度有时不能满足题目要求
2.2 O(nlogn)算法(埃氏筛)
定理:一个质数*任何一个不为1的正整数=合数
有了定理之后,就可以通过定理优化代码降低时间复杂度,下面是具体思路
Eratosthenes筛选方法(Eratosthenes Sieve Method)
假设有一个筛子存放1~N,例如:
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 .........N
先将 2的倍数 筛去:
2 3 5 7 9 11 13 15 17 19 21..........N
再将 3的倍数 筛去:
2 3 5 7 11 13 17 19..........N
之后,再将5的倍数筛去,再来将7的质数筛去,再来将11的倍数筛去........,如此进行到最后留下的数就都是质数,这就是Eratosthenes筛选方法(Eratosthenes Sieve Method)。
代码:
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
int primes[1000000];
int cnt;
bool notprime[1000000];
void set_prime()
{
notprime[1]=true;
for(int i=2;i<1000000;i++)
{
if(!notprime[i])
{
primes[++cnt]=i;
}
for(ll j=(ll)i*i;j<1000000;j+=i)//保证每一个遍历的值都没被筛过
{
notprime[j]=true;
}
}
}
int main()
{
set_prime();
for(int i=1;i<=cnt;i++)
{
cout<<primes[i]<<endl;
}
return 0;
}
模拟发现,有一些数被筛了不止一次,可能还有更优解
2.3 O(n)算法(线性筛)
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
int primes[1000000];
bool notprime[1000000];
int cnt,n;
int main()
{
cin>>n;//打印范围
for(int i=2;i<=n;i++)
{
if(!notprime[i]) primes[++cnt]=i;
for(int j=1;j<=cnt&&i*primes[j]<=n;j++)
{
notprime[i*primes[j]]=true;
if(i%primes[j]==0) break;
}
}
for(int i=1;i<=cnt;i++)
{
cout<<primes[i]<<endl;
}
return 0;
}
3 计算因数和
直接上例题:
寻找完数
【问题描述】
完数是指一个整数恰好等于它的因子和(除自身外),则称这个数为完数。从键盘先后输入两个不大于999的正整数m和n,若m>n,则交换两数,然后求m和n之间(m和为正数且m≤n)的所有完数
【输入形式】
先后输入两个正整数m和n,用逗号分隔
【输出形式】
输出所有完数,每两个数之间用号分隔若输入非法,则输出error
【样例输入】
1,2000
【样例输出】
6,28,496
【样例说明】
无
【评分标准】
正确性
注意:没有考虑输出的逗号(处理方法:第一个数单独输出)
#include<bits/stdc++.h>
using namespace std;
int m,n,j,i;
bool factorSum(int n)
{
int sum=0;
for (i=1;i*i<=n;i++)
{
if (n%i==0&&n!=i)
{
if (i==1||i*i==n) sum+=i;
else sum+=i+n/i;
}
}
return j==sum;
}
int main()
{
scanf("%d,%d",&m,&n);
if(m<=0||n<=0||m>9999||n>9999)
{
printf("error");
return 0;
}
if(m>n)
{
swap(m,n);
}
for(j=m;j<=n;j++)
{
if(factorSum(j)) printf("%d,",j);
}
return 0;
}