这道题我们得用素数筛,到不是要判断某个数是否是质数,而是要在计算素数的过程中算出每一个数的最小质因数,对素数筛有这个功能!
首先我们看素数筛的步骤;
我们设计一个bool数组prime[N],prime[i]=1时i为非素数,反之为素数;
我们从2开始遍历,终止条件是我们要判断的区间的右端点,即右端点为N;
1:如果prime[i]=0,即i是素数,我们进入循环
(1)从2*i开始,记为j,遍历到N,每次递增i,将这一过程的prime[j]记为1【因为这一过程中的j都是i的倍数,定然不是素数,所以prime[j]=1】
2:如果prime[i]=1,即不是素数,则continue;
这样一套下来,prime数组里记录的就是一个数是否是素数的信息了;
那么我们怎么在这个过程中找到一个数的最小质因子呢?可能有的人已经发现了,这个最小质因子就是对应的i,什么意思呢?意思是当prime[i]=0时,我们进入循环,其中所有遇到的数的最小质因数就是i了;
有了以上算法,我们就可以开始计算了;
#include<iostream>
#include<algorithm>
#include<vector>
using namespace std;
const int N=900010;
bool prime[N+10];
int mi[N];//mi[i]存储i的最小质因数
int l,r;
void getprime(){
for(int i=2;i<=N;i++){//循环每一个数
if(prime[i]) continue;//如果这个数不是素数,那么就跳过
for(int j=i*2;j<=N;j+=i){//将所有素数的X倍都记为非素数
prime[j]=1;
mi[j]=i;//i是j的最小质因数
}
mi[i]=i;//质数的最小质因数是自己
}
mi[1]=1;//这里算不到1,所以得我们自己初始化
}
那么接下来我们又遇到一个问题,我们怎么用以上信息将一个数质因数分解呢?
其实很简单,我们计算X时只需要进行以下循环即可;
首先我们有一个vector来存储答案,变量明为ans
1:如果X==1成立我们就退出循环
2:如果不成立我们进入以下操作
(1)将mi[X]push进ans
(2)X/=mi[X]即用X的最小质因数更新X
这么一套下来后ans里存储的就是X的质因数了;
接下来就是全套代码了;
/**
* main函数返回值不能为void,否则会汇编出错,请使用int main(),并在最后return 0。
* 虽然VC等windows下的编译器支持,但C/C++标准中不允许使用void main()!
*/
#include<iostream>
#include<algorithm>
#include<vector>
using namespace std;
const int N=900010;
bool prime[N+10];
int mi[N];
int l,r;
void getprime(){
for(int i=2;i<=N;i++){
if(prime[i]) continue;
for(int j=i*2;j<=N;j+=i){
prime[j]=1;
mi[j]=i;
}
mi[i]=i;
}
mi[1]=1;
}
int main(){
getprime();
cin>>l>>r;//输入需要遍历的区间
for(int i=l;i<=r;i++){
vector<int> ans;
int p=i;
while(p!=1){
ans.push_back(mi[p]);
p/=mi[p];
}
cout<<i<<'=';
sort(ans.begin(),ans.end());//将ans排个序
for(int i=0;i<ans.size();i++){//输出ans
cout<<ans[i];
if(i!=ans.size()-1) cout<<'*';
}
cout<<endl;
}
}