2017蓝桥杯C++B:等差素数列(枚举优化)

二、题目:等差素数列

2,3,5,7,11,13,….是素数序列。
类似:7,37,67,97,127,157 这样完全由素数组成的等差数列,叫等差素数数列。
上边的数列公差为30,长度为6。

2004年,格林与华人陶哲轩合作证明了:存在任意长度的素数等差数列。
这是数论领域一项惊人的成果!

有这一理论为基础,请你借助手中的计算机,满怀信心地搜索:

长度为10的等差素数列,其公差最小值是多少?

注意:需要提交的是一个整数,不要填写任何多余的内容和说明文字。


  • 分析思路:
    常见素数列:2,3,5,7,11,13,17,19,23…
    枚举法
    枚举首项:a[i]
    枚举公差: 1   2+3=5可以,3+5=8不符合
                    2
                    3
                    …
    公差的极限是最后数列最后一项-首项
    公差max-a[i],在每个公差过程中累加还要枚举个数
    从头到尾找10个

  • 代码:

#include<iostream>
#include<algorithm>
#include<set>
using namespace std;

typedef long long LL;
set<int>all;
bool isPrime(LL t){
	for(int i=2;i<t/2;i++){  //除2或者开更号 
		if(t%i==0)  //能否被整除,判断是否为素数 
		return false;
	}
	return true; 
} 
int f(LL a[],int n){ //把5000长度存储 ,已经是素数的数列中,找等差的素数列 
	for(int i=0;i<n;i++){   
		LL first=a[i];  //首项 
		for(int delta=1;delta<a[n-1]-first;delta++){ //delta枚举公差,考虑极限最大的减第一个 
		int m=first; //考虑首相 
		for(int j=1;j<10;j++){ //从首相开始加9次,若全为素数,则成功 
			m+=delta; //j每走一次,m加一次delta 
			if(all.find(m)==all.end()) //,找不到m不是素数 
			break;
			if(m>a[n-1]) break; //m超出范围 
			if(j==9)  //已经找到第10项
			return delta; 
		}	
		}
	} 
	return -1; //中间未找到 
}
const int N=5000;  //目前先定为找到5000
LL a[N];  //素数列 
int main(){
	a[0]=2;  //第一个素数 
	a[1]=3;  //第二个素数 
	all.insert(2); //2
	all.insert(3);  //3
	int index=2;
	LL t=5;  //a【0】+a【1】=5 
	while(index<N){
		if(isPrime(t)){  //如果是素数 
			a[index++]=t;  //找到素数填到数组中 
			all.insert(t);
		}
		t++;
	}
	cout<<f(a,N)<<endl;
	return 0;
} 

答案:210
在这里插入图片描述

发布了137 篇原创文章 · 获赞 7 · 访问量 2万+

猜你喜欢

转载自blog.csdn.net/gl620321/article/details/105333398
今日推荐