质数
定义
大于等于2的整数中只有1和它本身的因数的数称之为质数(素数)。
选自题目acwing 866 867 868.
试除法求质数:
由定义的方法
时间复杂度o(n)
for (int i = 2;i <= n; i ++)
if(n%2==0) return ture;
else return false;
因数都是成对出现的,即i*j=n;i和j都是n的因数。
所以必定存在n>m或者m>n的情况,所以枚举的时候我们从小到大枚举只需要枚举n/i就可以了,最大枚举到根号n的情况。
时间复杂度o(根号n)
for (int i = 2;i <= n/i; i ++)
if(n%i==0) return false;
return true;
分解质因数
类似的思想,我们同样是从小到大试除
由于所有的合数都是由质数相乘得来的,所以在遍历的时候就可以不用考虑除以合数的情况,依旧从小到大遍厉就可以了
时间复杂度o(根号n)
//计算总数
cin >> n;
s=0;//计数
for(int i = 1; i <= n; i ++)
{
if(n%i==0)
{
// int s = 0;
while (n%i==0)
n/=i;
s++;
//printf("%d,%d ",i,s);
}
}
s++;
if(n>1) printf("%d,%d",n,++s);
//每个质因数都计算吧=的情况只需要把s放入第一个if循环内然后输出就可以了
筛质数
还是利用所有合数都可以分解为质数的性质
前P个数中的素数的个数利用筛除,把1~p-1 的范围内的所有的数的倍数都筛除,余下的就都是素数。
时间复杂度约为n(log n)
int primes[N], cnt; // primes[]存储所有素数
bool st[N]; // st[x]存储x是否被筛掉
void get_primes(int n)
{
for (int i = 2; i <= n; i ++ )
{
if (st[i]) continue;
primes[cnt ++ ] = i;
for (int j = i + i; j <= n; j += i)
st[j] = true;
}
}
但是在数据过大的时候,朴素的筛选法就不太行了,就可以优化成线性筛法
还是利用了之前的两个数相乘,避免了部分数的重复bool赋值
int primes[N], cnt; // primes[]存储所有素数
bool st[N]; // st[x]存储x是否被筛掉
void get_primes(int n)
{
for (int i = 2; i <= n; i ++ )
{
if (!st[i]) primes[cnt ++ ] = i;
for (int j = 0; primes[j] <= n / i; j ++ )
{
st[primes[j] * i] = true;
if (i % primes[j] == 0) break;
}
}
}
南昌理工学院 acm集训队