#include <stdio.h>
#include <math.h>
int Isprime(int e){
int i;
if(e<=1)
return 0;
else{
for(i=2;i<=sqrt(e);i++){ ///求素数问题,必须是开平方
if(e%i==0)
return 0;
}
return 1;
}
}
int main()
{
int n;
int m;
int count[1000001]; //必须大于100003?还是不懂为什么
scanf("%d",&n);
int j;
for(int i=1,j=0;i<=1000001;i++){
if(Isprime(i)==1){
count[j]=i;
j++;
}
}
while(n--){
scanf("%d",&m);
int turn=0;
for(int j=1;(count[j]<=m)&&count[j]!=0;j++){ //加一个判断count了里面是不是为零的情况
if((count[j]-count[j-1])==1||(count[j]-count[j-1])==2){
turn++;
}
}
printf("%d\n",turn);
}
return 0;
}
出现的问题:
1.求素数:
普通求素数的方法
在判断能不能被1和他本身的其他数字整除的时候,即 for(i=2;i<=sqrt(e);i++)
这条语句中一般判断的条件式sqrt(i)或者是i/2,但是这两种方法所用的时间是不同的,循环次数前者较少,可以减少程序的运行时间,在以后的代码编写中 ,尽量全部都用前者,也就是开平方。
(在此补充一下为什么判断到开平方就可以:因为一个数如果他不是素数的话,就是两个数的乘积,这两个因子中一定有一个是小于sqrt的,所以说只要找到较小的因子就行了)
2.超时怎么办,循环次数太多怎么办
因为这个代码中要求有多组测试数据,所以我在原来的代码中先有一个while循环,表示测试数据的组数,再在while里调用一个有两重for循环的判断素数的函数,这样循环就一共有三层了,时间复杂度就大大增加了。所以,最终,我想了一个办法,先求出要求的某范围内的所有的素数,放在一个数组中,这是一点;再一个就是,就像这道题目中的要求,要求输入的数字不超过一百万万,所以我就定义了一个1000001的数组存放1000001以内的素数,在最后的判断中:
for(int j=1;(count[j]<=m)&&count[j]!=0;j++){ //加一个判断count了里面是不是为零的情况
if((count[j]-count[j-1])==1||(count[j]-count[j-1])==2){
turn++;
}
#include <math.h>
int Isprime(int e){
int i;
if(e<=1)
return 0;
else{
for(i=2;i<=sqrt(e);i++){ ///求素数问题,必须是开平方
if(e%i==0)
return 0;
}
return 1;
}
}
int main()
{
int n;
int m;
int count[1000001]; //必须大于100003?还是不懂为什么
scanf("%d",&n);
int j;
for(int i=1,j=0;i<=1000001;i++){
if(Isprime(i)==1){
count[j]=i;
j++;
}
}
while(n--){
scanf("%d",&m);
int turn=0;
for(int j=1;(count[j]<=m)&&count[j]!=0;j++){ //加一个判断count了里面是不是为零的情况
if((count[j]-count[j-1])==1||(count[j]-count[j-1])==2){
turn++;
}
}
printf("%d\n",turn);
}
return 0;
}
出现的问题:
1.求素数:
普通求素数的方法
在判断能不能被1和他本身的其他数字整除的时候,即 for(i=2;i<=sqrt(e);i++)
这条语句中一般判断的条件式sqrt(i)或者是i/2,但是这两种方法所用的时间是不同的,循环次数前者较少,可以减少程序的运行时间,在以后的代码编写中 ,尽量全部都用前者,也就是开平方。
(在此补充一下为什么判断到开平方就可以:因为一个数如果他不是素数的话,就是两个数的乘积,这两个因子中一定有一个是小于sqrt的,所以说只要找到较小的因子就行了)
2.超时怎么办,循环次数太多怎么办
因为这个代码中要求有多组测试数据,所以我在原来的代码中先有一个while循环,表示测试数据的组数,再在while里调用一个有两重for循环的判断素数的函数,这样循环就一共有三层了,时间复杂度就大大增加了。所以,最终,我想了一个办法,先求出要求的某范围内的所有的素数,放在一个数组中,这是一点;再一个就是,就像这道题目中的要求,要求输入的数字不超过一百万万,所以我就定义了一个1000001的数组存放1000001以内的素数,在最后的判断中:
for(int j=1;(count[j]<=m)&&count[j]!=0;j++){ //加一个判断count了里面是不是为零的情况
if((count[j]-count[j-1])==1||(count[j]-count[j-1])==2){
turn++;
}
}
我原来的代码是没有count [ j ]!=0这个条件的话,会有这么一种情况,假如你的m值是999999,而你判断的素数值是从0到1000002的话999983就是最后一个素数,判断时他是最后一个,而且他是小于1000002的,所以还会进行一次循环,使i+1,但是999983是最后一个素数了,数组里下一个数值就是0了,这样的话,永远都会小于m,循环就会进行下去,造成程序错误。所以得加上count [i]!=0的条件。如果没有这个的话,也可以让我们寻找素数的范围扩大到1000005,这样的话,下一个素数就是1000003,他是大于1000000的,这样会使程序正确的停止。总结为这样,必须让找出来的素数中最后一个是大于你给出的数值m。