质数距离(C++筛素数模板题)

2023-09-21 13:59:33

给定两个整数 L 和 U,你需要在闭区间 [L,U] 内找到距离最接近的两个相邻质数 C1 和 C2(即 C2−C1 是最小的),如果存在相同距离的其他相邻质数对,则输出第一对。

同时,你还需要找到距离最远的两个相邻质数 D1 和 D2(即 D1−D2是最大的),如果存在相同距离的其他相邻质数对,则输出第一对。

输入格式

每行输入两个整数 L 和 U,其中 L和 U 的差值不会超过 106106。

输出格式

对于每个 L和 U,输出一个结果,结果占一行。

结果包括距离最近的相邻质数对和距离最远的相邻质数对。(具体格式参照样例)

如果 L 和 U之间不存在质数对,则输出 There are no adjacent primes.

数据范围

1≤L<U≤2^31−1

输入样例:
2 17
14 17
输出样例:
2,3 are closest, 7,11 are most distant.
There are no adjacent primes.

 思路

因为这个数据范围太大,到了2^31次直接筛选一遍绝对会超时间。但是我们只需判断l-r之中的数,因此有没有一种算法能只筛出l-r之中的素数?

根据数学定理,一个合数n,必定能被一个不是自己的质数x整除,且x<=根号n。

因此我们只需将1-根号r中的所有质数筛选出来,然后将他们在l-r中的倍数删除,即可得到l-r中的质数。最后直接遍历一遍就能得到答案

#include<iostream>
#include<cstring>

using namespace std;

typedef long long LL;

const int N = 1e6 + 10; // l-r的最大距离 
LL primes[N], cnt;
bool st[N];

void init(int n)
{
	//因为st和primes有重用,因此每次开始都置为0 
	memset(st, 0, sizeof st);
	cnt = 0;
	
	for(int i = 2; i <= n; i ++)
	{
		if(!st[i]) primes[cnt ++] = i;
		
		for(int j = 0; primes[j] * i <= n; j ++)
		{
			st[primes[j] * i] = true;
			if(i % primes[j] == 0) break;
		}
	}
}

int main()
{
	int l, r;
	while(cin >> l >> r)
	{
		init(50000);	//因为st和primes有重用,因此每次开始都筛选一遍,之所以是50000,因为50000^2 = 2.5e9 > 2^31 
		memset(st, 0, sizeof st);//后面会重用
		 
		for(int i = 0; i < cnt; i ++)
		{
			LL p = primes[i];
			
			for(LL j = max(p * 2, (l + p - 1) / p * p); j <= r; j += p)// 埃式筛法j从p*2开始,(l + p - 1) / p * p是上取整,确保开始的j大于l
				st[j - l] = true; //下标有限,利用位移操作	
		} 
		
		cnt = 0;
		for(int i = 0; i <= r - l; i ++)
			if(!st[i] && i + l >= 2)//1不是质数,也没被筛过,因此要求从2开始即i + l >=2 
				primes[cnt ++] = i + l;
		
		if(cnt < 2) puts("There are no adjacent primes.");//质数数量不够凑不够
		 
		else
		{
			int minp = 0, maxp = 0;
			
			for(int i = 0; i + 1 < cnt; i ++) //遍历所有指数对 
			{
				int d = primes[i + 1] - primes[i];
				if(d < primes[minp + 1] - primes[minp]) minp = i;
				if(d > primes[maxp + 1] - primes[maxp]) maxp = i;			
			}
			
			cout << primes[minp] << ',' << primes[minp + 1] << " are closest, " <<
			primes[maxp] << ',' << primes[maxp + 1] << " are most distant." << endl;
		} 
	} 
	
	return 0;	
} 

更多推荐

web自动化测试 —— cypress测试框架

一、cypress简介基于JavaScript的前端测试工具可以对浏览器中运行的任何内容进行快速、简单、可靠的测试对每一步操作都支持回看覆盖了测试金字塔模型的所有测试类型【界面测试,集成测试,单元测试】底层协议不采用WebDriver>Cypress官网:https://www.cypress.io/二、cypress

随机抽样一致RANSAC

文章目录RANSAC简介RANSAC算法Ransac在3D视觉中的用法直线拟合单应性矩阵拟合RANSAC的优缺点RANSAC的优点RANSAC的缺点RANSAC在弯曲场景中的缺点:RANSAC适用场景RANSAC简介RANSAC是RANdomSAmpleConsensus的缩写,中文翻译叫随机采样一致。它可以从一组观测

嵌入式开发环境Vscode开发STM32单片机程序

STM32单片机非常强大,大多数教程都是使用keil编译器,keil是收费的而gcc是开源免费的。这里介绍一些使用gcc+vscode开发单片机程序的经验。(这里不解释gcc是什么)。​第一:环境准备gccARM开发者官网https://developer.arm.com/我有个习惯:尽量使用免安装版软件,直接解压到软

华为云云耀云服务器L实例评测-搭建基于hexo的个人博客

1、演示访问地址:演示传送门开头先来一个效果图。2、准备服务器前面有介绍了一下华为云云耀云服务器L实例评测以及简单的配置用法,具体可以看上篇的博客。https://blog.csdn.net/yongqing_/article/details/132867889我这里用的是华为云云耀云服务器L实例,2核2G的配置。然后

Python 数独求解器

文章目录使用回溯算法在Python中解决数独总结Sudoku(数独)是一种基于逻辑的数字填充谜题游戏,最受喜爱的是那些热爱逻辑和推理的人。解决数独谜题有助于提高集中注意力和逻辑思维能力。本文介绍了如何使用Python解决数独谜题。使用回溯算法在Python中解决数独在寻找计算问题的解决方案时,我们经常使用回溯算法。在解

关于安卓SVGA浅尝(一)svgaplayer库的使用

关于安卓SVGA浅尝(一)使用相关链接SVGA官网SVGA-github说明文档背景项目开发,都会和动画打交道,动画的方案选取,就有很多选择。如Json动画,svga动画,gif等等。各有各的优势。目前项目中用到了svga的动画,因此,就有了这一系列的文章。使用(1)引入首先,引入的方式,大致有两种:一种是直接使用远程

玩玩“小藤”开发者套件 Atlas 200I DK A2 之部署智能语音助手

玩玩“小藤”开发者套件Atlas200IDKA2之部署智能语音助手0.背景1.安装flac2.创建自签名证书3.创建虚拟环境4.安装PyTorch5.安装PyTorch插件torch_npu6.安装APEX混合精度模块7.安装依赖库8.使用gradio启动智能语音助手9.访问智能语音助手0.背景总所周知,英伟达的GPU

c++编译过程-各阶段任务

首先,g++在编译源代码时,会经历下面几个阶段-E首先进行预处理,还是源代码格式.i-S编译器生成汇编语言.s-c汇编器生成二进制文件.o-链接库文件,其他代码.out一.预处理预处理主要是1.将#宏定义进行展开,2.将头文件内容替换3.去掉注释二.编译编译主要是将预处理后的代码转换成汇编语言:1.对代码进行语法分析,

AndroidUtil - 强大易用的安卓工具类库

官网https://github.com/Blankj/AndroidUtilCode/blob/master/README-CN.md项目介绍AndroidUtilCode🔥是一个强大易用的安卓工具类库,它合理地封装了安卓开发中常用的函数,具有完善的Demo和单元测试,利用其封装好的APIs可以大大提高开发效率,如

解锁黑科技!群晖管家+cpolar内网穿透,让你的本地黑群晖实现公网远程访问!

白嫖怪狂喜!黑群晖也能使用群晖管家啦!文章目录白嫖怪狂喜!黑群晖也能使用群晖管家啦!1.使用环境要求:2.下载安装群晖管家app3.随机地址登陆群晖管家app4.固定地址登陆群晖管家app自己组装nas的白嫖怪们虽然也可以通过在局域网使用黑群晖,但是群晖quickconnect需要绑定正版群晖账号,那么白嫖怪们要怎样在

【自动化测试】如何下载安装webdriver

1.下载合适的浏览器驱动2.配置环境变量写自动化脚本的时候经常会用到selenium,selenium来自webdriver模块,所以需要安装对应的webdriver驱动。1.查看自己浏览器的版本;发现我的浏览器版本已经升到了最新的版本,我参照这个链接,下载了最新版本的驱动,https://googlechromela

热文推荐