【模板】素数筛法和质因数分解 (素数、质因数分解题解)

素数筛法

常规思路:如果n能被i(2\leq i \leq \sqrt{n})整除,则不是素数。

素数筛选:换一个角度。当获得一个素数的时候,就把它的所有倍数标记为非素数。这样,当我们遍历到一个数时,如果其已经被标记,则说明存在一个更小的数,是它的因子,因此它不是素数,否则它是素数。

素数

题目描述

输入一个整数n(2<=n<=10000),要求输出所有从1到这个整数之间(不包括1和这个整数)个位为1的素数,如果没有则输出-1。

输入描述:

输入有多组数据。每组一行,输入n。

输出描述:

输出所有从1到这个整数之间(不包括1和这个整数)个位为1的素数(素数之间用空格隔开,最后一个素数后面没有空格),如果没有则输出-1。

输入

100

输出

11 31 41 61 71
#include<iostream>
using namespace std;
bool mark[10001];
int prime[10001]; //记录我们筛选出来的素数 
int primeSize;//筛选的素数个数 
void init()
{
	primeSize=0; 
	for(int i=1;i<10001;i++){
		mark[i]=false;
	}
	for(int i=2;i<10001;i++){
		if(mark[i]==true) continue;//如果被标记了,说明它是某个数的倍数 
		prime[primeSize++]=i;//否则说明它不被任何大于等于2的整除,是素数 
		for(int j=i*i;j<10001;j=j+i){//从i*i开始遍历i的倍数 
			mark[j]=true;	
		}
	} 
}int main(void) 
{
	init();
	int n;
	while(cin>>n){
		int count=0;
		for(int i=0;i<primeSize;i++){
			if(prime[i]<n&&prime[i]%10==1){
				if(count==0) cout<<prime[i];
				else cout<<" "<<prime[i]; 
				count++;
			}
		}
		if(count==0) cout<<"-1";
		cout<<endl;
	}
}

最朴素的素数判定:

#include<bits/stdc++.h>
using namespace std;
int judge(int n)
{
	if(n<=1) return false;
	for(int i=2;i*i<=n;i++)
	{
		if(n%i==0) return false;
	}
	return true;
}
int main(void)
{
	int n;
	while(cin>>n)
	{
		puts(judge(n)?"yes":"no");
	}
	return 0;
}

质因数分解

首先筛选出素数,然后只要能被素数整除,就依次用n去除以该素数。如果不能被该数继续整除就选择下一个素数。直到为1。

技巧:这里只筛选了100000以内的素数,这是因为如果存在比100000大的素数因子,则一定没有被除到1且这样的素数因子一定只有1个。

质因数的个数

题目描述

求正整数N(N>1)的质因数的个数。 相同的质因数需要重复计算。如120=2*2*2*3*5,共有5个质因数。

输入描述:

可能有多组测试数据,每组测试数据的输入是一个正整数N,(1<N<10^9)。

输出描述:

对于每组数据,输出N的质因数的个数。

输入

120

输出

5
#include<iostream>
using namespace std;
bool mark[100001];
int prime[100001]={0};
int primeNum=0;
void init()
{
	//素数筛选
	for(int i=0;i<100001;i++) mark[i]=false;
	for(int i=2;i<100001;i++)
	{
		if(mark[i]==true) continue;
		else{
			mark[i]=false;
			if(i>=1000) continue;
			for(int j=i*i;j<100001;j+=i)
			{
				mark[j]=true;
			}
		}
	 } 
	 for(int i=2;i<100001;i++)
	 {
	 	if(mark[i]==false)
	 	{
	 		prime[primeNum]=i;
		 	primeNum++;	
		 }
	 }
}
int main(void)
{
	init();
	int n;
	while(cin>>n)
	{
		int ans=0;
		for(int i=0;i<primeNum;i++)
		{
			if(n%prime[i]==0)
			{
				while(n%prime[i]==0)
				{
					ans++;
					n=n/prime[i];
				}
			}
		}
		if(n!=1) ans++;
		cout<<ans<<endl;
	}
	return 0;
}

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值