PAT 1007 素数对猜想

题目描述:

让我们定义d​n​​为: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,让计数自增一,最后输出即可。

所以问题的关键就变成了计算给定n范围内的素数问题了。

一般会想到直接遍历就好了,当然可以实现,但是时间复杂度太高,效率过低。

这里提供一种思路:当你发现2是素数的时候,那么2的倍数,像4,6,8,10等是不是都不可能是素数了?3是素数的时候,那么3的倍数也都不会是素数了,以此类推。你只需要从2开始(因为1不是素数),每遇到一个素数,然后将是其倍数的数全都删去,那么最后数组中就会只剩下是素数的数字了。

此题的代码如下: 

#include
using namespace std;
const int maxn=100005;  //所能输入的n的最大范围; 
bool is_prime[maxn];	// 判断是否为素数的数组; 
int c=0;				//记录prime数组的大小; 
int prime[maxn];		//存储所有的素数; 
void set_prime(int n)
{
	for(int i=1;i<=n;i++)
		is_prime[i]=true;
	is_prime[1] = false;//1不属于素数; 
	for(int i=1;i<=n;i++){
		if(is_prime[i]){
			prime[c++]=i;
			for(int j=i;j<=n;j+=i){ //去掉i的倍数数字; 
				is_prime[j]=false;
			}
		}
	}
	
}
int main()
{
	int n,count=0;
	cin >> n;
	set_prime(n);
	for(int i=0;i

小结:

以前我们遇到的总是简单的判断是不是素数就好了,这道题提升了一点高度,主要考虑的应该是算法复杂度的问题,因为如果不直接筛选素数,每一个数都去判断是不是素数,那么时间复杂度会过高。

 

你可能感兴趣的:(PAT,乙级,c++编程)