PAT乙级1007

题目链接

https://pintia.cn/problem-sets/994805260223102976/problems/994805318855278592

题解一

根据题意,素数对有两个特点:差为2、相邻,所以我们可以从3开始枚举每一对数字,然后再判断它们两个是不是素数。

这道题刚开始还是有一个点超时(TLE)了,主要原因有三点:

  1. 枚举方法太low,没有利用偶数不可能是素数这一性质。(题解一已处理)

    我刚开始是枚举的是3,5、4,6、……;后来改成了3,5、5,7、……

  2. 判断素数方法太low,用sqrt较好,当然也有更快的方法。(题解一已处理)

  3. for循环中可能重复判断5是不是素数(让我想起来了动态规划..…),增加了时间复杂度(题解一未处理,在题解二中处理)

在网上查题解发现我在判断素数的时候也忘记了处理1不是素数和2是素数的情况。

// PAT BasicLevel 1007
// https://pintia.cn/problem-sets/994805260223102976/problems/994805317546655744

#include <iostream>
#include <cmath>
using namespace std;

bool isPrime(int num);

int main()
{
    // 获取用户输入的数字
    int N=0;
    cin >> N;

    // 判断素数对的个数
    int count=0;
    for(int i=3;i+2<=N;i+=2){   // 偶数一定不是素数
        if(isPrime(i)&&isPrime(i+2)){
            count++;
        }
    }

    // 输出结果
    cout << count;

    //system("pause");
    return 0;
}

// 判断是否为素数
bool isPrime(int num)
{
    // 并没有处理num为2的情况

    // 用这种方法找素数找的比较快,相当于i<sqrt(num),但这样精度可能损失,导致错误
    for (int i = 2; i*i <= num; i++){
        if (num%i==0)
            return false;
    }

    // 边界条件,1不是素数
    return num == 1?false:true;
}

题解二

针对题解一中重复判断5是否为素数的问题,我们至少有两种方法解决:

  1. 建一个数组存储所有素数
  2. 用一个变量存储上一个素数且不断更新

网上搜到的题解有方法一,也有方法二,这里采用后者。

// PAT BasicLevel 1007
// https://pintia.cn/problem-sets/994805260223102976/problems/994805317546655744

#include <iostream>
#include <cmath>
using namespace std;

bool isPrime(int num);

int main()
{
    // 获取用户输入的数字
    int N=0;
    cin >> N;

    // 素数对的个数
    int count=0;

    // 上一个素数
    int lastPrime=2;    

    // 计算素数对个数
    for(int i=3;i<=N;i+=2){   // 偶数除了2一定不是素数
        // 找到新的素数
        if(isPrime(i)){
            
            // 判断是否为素数对
            if(i-lastPrime==2){ //两个素数之差为2
                count++;    // 计数
            }

            // 更新上一个素数
            lastPrime=i;
        }
    }

    // 输出结果
    cout << count;

    //system("pause");
    return 0;
}

// 判断是否为素数
bool isPrime(int num)
{
    // 1不是素数
    if(num<=1)
        return false;

    // 用这种方法找素数找的比较快,相当于i<sqrt(num),但这样精度可能损失,导致错误
    for (int i = 2; i*i <= num; i++){
        if (num%i==0)
            return false;
    }

    return true;
    
}

作者:@臭咸鱼

转载请注明出处:https://chouxianyu.github.io

欢迎讨论和交流!


posted @ 2019-08-04 23:45  臭咸鱼  阅读(356)  评论(0编辑  收藏  举报