只要记得需要优化一下,不用枚举到n,利用质数性质枚举到n/i就行
时间复杂度 根号n
#include
#include
using namespace std;
int n;
bool judge(int a)
{
if(a < 2)
return false;
for(int i = 2; i <= a / i; i ++ )
if(a % i == 0)
return false;
return true;
}
int main ()
{
cin>>n;
while(n -- )
{
int a;
cin>>a;
if(judge(a))
cout<<"Yes"<<endl;
else
cout<<"No"<<endl;
}
return 0;
}
正整数的因数分解可将正整数表示为一连串的质因子相乘,质因子如重复可以用指数表示。根据算术基本定理,任何正整数皆有独一无二的质因子分解式
主要是函数内的优化,首先还是n最多只有一个大于根号n的质因数,因此还是枚举到n/i,枚举完之后需要再判断一下是否大于1,如果大于1,则说明有大于根号n的质因数,直接输出就行。
时间复杂度根号n(介于logn 和根号n之间)
#include
using namespace std;
int n;
void solve(int a)
{
for(int i = 2; i <= a / i; i ++ )
{
if(a % i == 0)
{
int s = 0;
while(a % i == 0)
{
a /= i;
s ++;
}
cout<<i<<" "<<s<<endl;
}
}
if(a > 1)
cout<<a<<" "<<1<<endl;
cout<<endl;
}
int main ()
{
cin>>n;
while(n -- )
{
int a;
cin>>a;
solve(a);
}
return 0;
}
主要就是遍历一遍把前面一个小质数的倍数给ban掉。
时间复杂度nlnn ,也就是nlogn。
#include
using namespace std;
const int N = 1000010;
int n;
int cnt;
bool st[N];
void get_primes(int a)
{
for(int i = 2; i <= a; i ++ )
{
if(!st[i])
cnt ++;
for(int j = i + i; j <= a; j += i )
st[j] = true;
}
}
int main ()
{
cin>>n;
get_primes(n);
cout<<cnt<<endl;
return 0;
}
优化:筛的时候把ban掉的过程放进判断里,也就是只需要把质数的倍数ban掉。
时间复杂度:nloglogn,基本和O(n)一个级别。
#include
using namespace std;
const int N = 1000010;
int n;
int cnt;
bool st[N];
void get_primes(int a)
{
for(int i = 2; i <= a; i ++ )
{
if(!st[i])
{
cnt ++;
for(int j = i + i; j <= a; j += i )
st[j] = true;
}
}
}
int main ()
{
cin>>n;
get_primes(n);
cout<<cnt<<endl;
return 0;
}
可以看到在10e6下快了几倍。
除此之外还有线性筛法,在7次方或者更大数量级大概会再快一倍,在这里就不赘述了,感兴趣的可以自行百度。