题目推荐:http://ybt.ssoier.cn:8088/problem_show.php?pid=1151
https://www.luogu.com.cn/problem/P3383
第二个题数据规模有点儿doge,所以建议直接用欧拉筛来提交
第一种写法:朴素筛
1.O(n^2)写法
using namespace std;
//询问一个数,输出一行Yes或No。
int n;
bool pd=1;
int main()
{
scanf("%d",&n);
if(n==1)printf("No");//特判。
for(int i=2;i<n;i++)//枚举到n前一个。
{
if(n%i==0)
{
pd=0;
break;
}
}
if(pd)printf("Yes");
else printf("No");
return 0;
QWQ;
}
稍稍给它优化优化,枚举到√n;
2.O(n*√n)写法:
using namespace std;
//询问一个数,输出一行Yes或No。
int n;
bool pd=1;
int main()
{
scanf("%d",&n);
if(n==1)printf("No");//特判。
for(int i=2;i*i<=n;i++)//这次枚举到根号n,因为根号n到n之间的数都不是n的因数
{
if(n%i==0)
{
pd=0;
break;
}
}
if(pd)printf("Yes");
else printf("No");
return 0;
QWQ;
}
但是这样按照此题要判断多次,时间复杂度肯定很高是不行滴 试过
接下来再介绍两种高效率区间筛:
二:埃氏筛
当需要求某一区间[2,n]内的所有素数时,可以从2开始,对于当前素数p,将p^2p2后所有p的倍数筛去每次找到下一个没有被筛到的数就是一个素数。
#include<bits/stdc++.h>
using namespace std;
int a[100005],n,q,x;
bool ss(int x)
{
bool f=1;
for(int i=2;i<=sqrt(x);i++)
{
if(x%i==0)
{
f=0;
break;
}
}
return f;
}
int main(){
cin>>n>>q;
int sum=1;
for(int i=2;i<=n;i++){
if(ss(i)){
a[sum]=i;
sum++;
}
}
while(q--){
cin>>x;
cout<<a[x]<<endl;
}
return 0;
}
当然,这种算法并不完美,因为有些合数会被筛两次。
比如6,会被2筛一次,3一次,为了优化,我们用出了另一种更高效率的区间筛
所以:
三:欧拉筛
欧拉筛法的基本思想 :在埃氏筛法的基础上,让每个合数只被它的最小质因子筛选一次,以达到不重复的目的。
具体详解,请见:https://blog.csdn.net/qq_39763472/article/details/82428602
#include<bits/stdc++.h>
using namespace std;
int sum=1,n,m,x,a[100000001];
bool un[100000001];
void oula(int x){
for(int i=2;i<=n;i++){
if(un[i]==false){
a[sum++]=i;
}
for(int j=1;j<=sum && i*a[j]<=n;j++){
un[i*a[j]]=true;
if(i%a[j]==0) break;
}
}
}
int main(){
cin>>n>>m;
oula(n);
while(m--){
cin>>x;
cout<<a[x]<<endl;
}
return 0;
}
最后,奉上推荐题的AC代码,方便各位复制粘贴
1.
#include<iostream>
#include<cmath>
using namespace std;
bool judge(int x)
{
bool f=1;
for(int i=2;i<=sqrt(x);i++)
{
if(x%i==0)
{
f=0;
break;
}
}
return f;
}
int main()
{
int n;
int sum=0;
cin>>n;
for(int i=2;i<=n;i++)
{
if(judge(i))
{
sum++;
}
}
cout<<sum<<endl;;
return 0;
}
2.
#include<bits/stdc++.h>
using namespace std;
int sum=1,n,m,x,a[100000001];
bool un[100000001];
void oula(int x){
for(int i=2;i<=n;i++){
if(un[i]==false){
a[sum++]=i;
}
for(int j=1;j<=sum && i*a[j]<=n;j++){
un[i*a[j]]=true;
if(i%a[j]==0) break;
}
}
}
int main(){
cin>>n>>m;
oula(n);
while(m--){
cin>>x;
cout<<a[x]<<endl;
}
return 0;
}