题目分析
这道题和前面的素数对猜想的主要方法十分类似。为了达到题目的时间要求,需要对素数筛选的办法适当加快。在判定素数的过程尽可能加大步长后,最终各个测试点最长耗时6ms。另外,网上有不少人采取了开一个很大的数组存储各个素数的办法,但实际上这个问题完全可以用就地算法解决(空间复杂度
),不过开数组也不影响,而且有些地方判定素数的办法稍微复杂点也是可以过的,这题对复杂度的要求其实比较低,只要代码是对的,有个基本的优化就可以AC。
加速素数筛选的办法同1007的解析:
[PAT Basic Level] 1007、1008
不过这次不小心把修改步长的变量声明放错了地方,导致有两个点一直过不了,后来仔细检查终于发现,写代码还是要小心啊,再简单的问题编写不仔细也得花上几倍的时间才可能检查出问题所在,还是在编写代码之初就仔细考虑清楚后再写。
源代码
//2020.03.04
#include <stdio.h>
#include <cmath>
int getNextPrim(int num);
int main()
{
int order=0; //记录素数的序号
int count=0; //每10个数换行
int begin,end;
int prim=1; //素数搜索
bool lineFlag=false;
scanf("%d %d",&begin,&end);
while(order<end){
prim=getNextPrim(prim); //更新素数值
order++;
if(order<begin) continue; //未到输出条件
//否则
if(lineFlag){ //若换行标志为true
printf("\n");
lineFlag=false;
}
if(count) printf(" ");
printf("%d",prim);
count++;
if(count==10){ //输出满10个数
lineFlag=true;
count=0;
}
}
return 0;
}
int getNextPrim(int num)
{
if(num<2) return 2;
else if(num==2) return 3;
else if(num==3) return 5;
bool findPrim=true;
/*int gap=2; 之前将gap声明写在这里,导致错误一直没检查出来*/
while(num++){
if((num%6)!=1&&(num%6)!=5) continue;
int limit=sqrt((double)num);
int i=5;
int gap=2;
while(i<=limit){
if(num%i==0){
findPrim=false;
break;
}
i+=gap;
if(gap==2) gap=4;
else gap=2;
}
if(findPrim) break;
findPrim=true;
}
return num;
}