质数即素数 除了1和它本身以外没有其他的因子的数
合数 除了1和它本身以外,还有其他的因子
1既不是质数,也不是合数
a/b=k...r a=k*b+r r=a%b k=a/b
素数 (对于介于1到n的任意的一个数a n%a!=0 都除不尽) 1<a<n n%a!=0
余数不为零 除不尽 n%a!=0
余数为零 能整除 n%a==0
如果一个数n除了1和它本身外还有其他的因子,即合数,那么该因子要么是sqrt(n) ,要么是k与n/k
(即成对的出现在sqrt(n)的左右两侧)
如 4 1 2 4 (4是合数,它的除1和本身以外的其他因子是 sqrt(4)
8 1 2 | 4 8 (8是合数,它的除1和它本身以外的其他因子 2,8/2 成对分布在sqrt(8)的两侧)
假设n的一个因子为k,则它的另一个因子为n/k,要么k与n/k相等,要么 k与n/k成对分布在sqrt(n) 的两侧
求素数的两种常用方法:
1.暴力求解法 不仅可以判断某一个数书是不是素数,还可以按要求打印出一个素数表
2.打印素数表为了降低时间复杂度可以用素数筛选法
素数筛选法:
从2开始对这个区间进行遍历(已知2为素数),如果是2的倍数,移除。
如果不是素数在遍历过程中就被移除了,如果到了这个数,这个数还没有
被移除,则证明这个数是素数,并且移除该数的倍数。到最后留下的数即
所求区间内的素数
列: 求1-15 区间内的素数
2 3 4 5 6 7 8 9 10 11 12 13 14 15
2 3 5 7 9 11 13 15
2 3 5 7 11 13
const int maxn=16;
int prime[maxn], pNum;
bool p[maxn];
for(int i=2;i<maxn;i++){
if(p[i]==false){
prime[pNum++]=i;
for(int j=i+i;j<maxn;j+=i)
p[j]=true;
}
}
//用素数筛选法得到相应区间的素数表
如果不是连续区间得到素数那么用一般方法即可。
小技巧:题目要求第1e4个质数,如果不知道这个质数是否会越界那个就先求一下,确认无误后再写代码
质因子(因子的一种) :给定一个正整数n 如果它有质因子,那么它的质因子的分布有两种情况
1.所有的质因子都小于等于sqrt(n)
2.存在且只存在一个质因子大于等于sqrt(n){该质因子可能是n本身}, 其余的质因子都小于等于 sqrt(n)
质因数分解:把一个数分解成一个或者多个质因子相乘的形式 4=2*2 8=2*2*2 15=3*5 180=2*2*3*3*5
对一个数n分解成质因子相乘的形式:
前提知识:
质因子(因子的一种) :给定一个正整数n 如果它有质因子,那么它的质因子的分布有两种情况
1.所有的质因子都小于等于sqrt(n)
2.存在且只存在一个质因子大于等于sqrt(n){该质因子可能是n本身}, 其余的质因子都小于等于 sqrt(n)
注意:
1.整数范围内的质因子 打质数表的时候打到 1e5+10 就可以了
2.设一个结构体Factor 来存不同的质因子x和该质因子出现的个数 cnt
因为质数2*3*5*7*11*13*17*19*23*29就越界了,所以int型范围内的数的质因子数组开10大小即可
枚举1到sqrt(n)范围内的所有的质数p,判断p是不是n的因子
如果是,记录这个因子,并求得该因子在该数中出现的次数
如果不是,直接跳过
for(int i=0;i<pNum;i++){
if(n%prime[i]==0){
fac[num].x=i;
fac[num].cnt=0;
while(n%i==0){
fac[num].cnt++;
n/=i;
}
}
}
if(n!=1){
fac[num].x=n;
fac[num].cnt=1;
num++;
}