用一个数组来存储所有范围内数字的最小质因子。
从2开始依次向后进行操作->将数组中的下标与此数或此数的倍数相同的值赋为此数。
例:
a[2]= a[22] = a[23] = a[24]…=…a[2n] = 2
对于此值的倍数如:4,6,8 。已经赋过了而且是最小的质因子,又因为是依次向后顺序进行,会依次2,3,4,5,6,7,…n所以前面赋过了值,到后面还会遇到。这里就通过一个数组biao[]来判断是否之前给此值赋过值,通过 while (!biao[i])
来选择没有赋质因子的值。
代码如下:
#include<iostream>
#include<cmath>
#include<algorithm>
#include<vector>
#include<cstring>
#include <random>
#include <ctime>
using namespace std;
typedef long long ll;
int n;
const int N=1e6+5;
int res[N];
int biao[N];
int main()
{
int k = N;
cin>>n;
memset(res,0x3f3f3f3f,sizeof res);
for(int i = 2; i < k; ++i)
{
if( !biao[i] )
{
res[i] = i;
for (int j = 2; i*j < k; j++)
{
biao[j*i]=true;
res[j*i] = min(res[j*i],i);
// printf("\n");
}
}
}
int a;
for (int i = 0; i < n; i++)
{
scanf("%d",&a);
printf("%d\n",res[a]);
}
return 0;
}
因为筛选每一个没有赋过值的值时都会找它的倍数,所以可能会有查到同一个值的情况,所以赋值要比较原来的以及现有数值的大小,因此选择将数组中每个值都赋为最大。依次往后查找没有赋过值的数(通过另一个数组来通过下标 记录是否赋过值)
if( !biao[i] )
{
res[i] = i;
for (int j = 2; i*j < k; j++)
{
biao[j*i]=true;
res[j*i] = min(res[j*i],i);
}
同时也可以再次判断是否给这个值赋过值来实现此功能。
if( !biao[i] )
{
res[i] = i;
for (int j = 2; i*j < k; j++)
{
if( !biao[j*i] )
{
biao[j*i]=true;
res[j*i] = i;
}