题目1007 素数对猜想
让我们定义dn为:dn=pn+1−pn,其中pi是第i个素数。显然有d1=1,且对于n>1有dn是偶数。“素数对猜想”认为“存在无穷多对相邻且差为2的素数”。
现给定任意正整数N(<),请计算不超过N的满足猜想的素数对的个数。
输入格式:
输入在一行给出正整数N。
输出格式:
在一行中输出不超过N的满足猜想的素数对的个数。
输入样例:
20
输出样例:
4
思路一
根据素数定义:只有1和改数本身两个正因数的数。第一个想到暴力解法但是时间复杂度会是,一般情况会超时。根据题意,首先要根据定义先找出素数,然后找出符合题意的素数对输出。
代码一
#include <stdio.h>
//定义为只有1与该数本身两个正因数的数
int main(){
int a[10000];
int n, count, k= 0, num= 0;
scanf("%d", &n);
for(int i= 1; i<= n; i++){
count= 0;
for(int j= 1; j<= i; j++){
if(i% j== 0) count++;
}
if(count== 2){//素数
a[k++]= i;
}
}
for(int i= 0; i< k; i++){
if(a[i+1]-a[i]== 2) num += 1;
}
printf("%d", num);
return 0;
}
问题
暴力解法时间复杂度较高,一般情况无法获得满分,需要找到更优解。
思路二
通过设置一个函数来判断是否为素数来代替二次循环,以减少时间复杂度。函数部分循环条件中参考因数的定义,若x为y的因数,那么也是y的因数,为了优化代码,可以将终止条件尽量减小为。在主函数中遍历输入N,其中开始条件为i=5,因为通过基本遍历已知在5之前没有满足条件的素数对。
代码二
#include <stdio.h>
#include <stdbool.h>
bool isprime(int a){
for(int i = 2; i*i <= a; i++)
if(a%i == 0) return false;//有除1以外的因数,非素数
return true;
}
int main(){
int n, cnt = 0;
scanf("%d", &n);
//遍历N
for(int i = 5; i <= n; i++){
//满足两个数同时为素数且差值为2的苛刻条件
if(isprime(i-2) && isprime(i)) cnt++;
}
printf("%d", cnt);
return 0;
}
总结
在C语言标准中没有定义bool类型,需要导入头文件#include <stdbool.h>就可以使用。