PAT Basic(乙级)---1007(20分)素数对猜想

让我们定义dn​​为:d​n​​=p​n+1​​−p​n​​,其中p​i​​是第i个素数。显然有d​1​​=1,且对于n>1有d​n​​是偶数。“素数对猜想”认为“存在无穷多对相邻且差为2的素数”。

现给定任意正整数N(<10​5​​),请计算不超过N的满足猜想的素数对的个数。

输入格式:

输入在一行给出正整数N。

输出格式:

在一行中输出不超过N的满足猜想的素数对的个数。

输入样例:

20

输出样例:

4

 


算法一思路:

  • 题目的意思就是从2-n之间,有多少对相邻且差为2的素数对。那么首先要得到所有的素数,可以通过循环来判断。
  • 建立数组list,设立两个索引,第一个索引为left,即第一个位置,初始化为0;第二个索引right为1。
  • 当list[right]不为空时,循环判断是否为素数。.....我只能想到让list[right]这个数依次去对2到(list[right]-1)取余,如果值为0,那么就出循环,判断为非素数。
  • 若为素数,继续判断是否相差为2。最后left=right,right加1。
  • (但这样时间复杂度有点高呀,....首先要遍历链表所有值,每次还要循环取余判断该值是否为素数)

报错代码:

 

#include 
#include 

int main(){
  int n;
  int i;
  scanf("%d", &n);
  if(n<=1) return 0;
  int *list = (int*)malloc(sizeof(int)*(n-1));
  
  //初始化
  for(i=0;i

结果:

PAT Basic(乙级)---1007(20分)素数对猜想_第1张图片

。。。。运行超时?! 


 

调试:

运行超时可能情况:

  1. 死循环
  2. 数据太大时,超过了运行时间上限

死循环是不可能死循环的,赋值的for循环不可能死循环,之后的判断素数的for也是不可能死循环的,i是正数,i++无论如何也是可以弹出循环的。while也是当list[right]!=-1时便跳出,边界添加n=1和2的时候都满足。

那就只能是数据太大时超过了题目规定时间上限,果然,时间复杂度太高了。

那。。。只能换一种方法了

 


算法二思路:

  • 没有必要以数组来存储所有的数,因为判断素数对过后,前一个数之后就不会用到了,后一个数可以用一个临时变量暂时存储。比如3和5,判断完之后3就不用了,用临时变量存储5然后继续找。
  • 判断k是否为素数只需要除到根号k就行了。一个数k如果不是素数那么一定存在若干个(不少于2个)因子,除去1之后,设最大的因子为p,p*p一定小于等于k,所以p<根号k。那么在2~根号k之间就可以找到最大因子,则不为素数。

 


代码:

 

#include
#include
int main()
{
    int i,j,k,temp,n=0;
    int s=2;
    scanf("%d",&k);
    if(k==1) return 0;
    else{
        for(i=3;i<=k;i++)
        {
            temp=sqrt(i);
//在2到根号i间找是否有因子
            for(j=2;j<=temp;++j)
                if(i%j==0) break;
       //没有找到时j>=temp+1,则为素数
            if(j>=temp+1)
            {
                if((i-s)==2)
                    n++;
                s=i;
            }
        }
 }
        printf("%d",n);
        return 0;
}

参考:http://https://blog.csdn.net/qq_41608020/article/details/79232447

舒服。

 

 

 

 

 

 

 

 

 

你可能感兴趣的:(PTA乙级刷题日志)