PAT乙级1007
题目链接
https://pintia.cn/problem-sets/994805260223102976/problems/994805318855278592
题解一
根据题意,素数对有两个特点:差为2、相邻,所以我们可以从3开始枚举每一对数字,然后再判断它们两个是不是素数。
这道题刚开始还是有一个点超时(TLE)了,主要原因有三点:
-
枚举方法太low,没有利用偶数不可能是素数这一性质。(题解一已处理)
我刚开始是枚举的是3,5、4,6、……;后来改成了3,5、5,7、……
-
判断素数方法太low,用sqrt较好,当然也有更快的方法。(题解一已处理)
-
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是否为素数的问题,我们至少有两种方法解决:
- 建一个数组存储所有素数
- 用一个变量存储上一个素数且不断更新
网上搜到的题解有方法一,也有方法二,这里采用后者。
// 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
欢迎讨论和交流!