质数距离

题目TP门

题目描述

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

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

输入格式

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

输出格式

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

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

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

样例

样例输入

2 17
14 17

样例输出

2,3 are closest, 7,11 are most distant.
There are no adjacent primes.
数据范围

1≤L<R≤2147483647

解析

L,R范围很大,即使是线性筛法也无法在有限时间内筛选出质数。

我们知道,在任何一个合数n中,必有一个小于sqrt(n)的因子。

所以先用任意筛法(时间复杂度<=O(n))筛出所有在sqrt( R )中的质数。

把这些数记为p。


不难想到,在[L,R]中的数,只要不被p整除,就是质数。找出[L,R]中的质数之后,后面的操作就很简单了。

于是我就想到了枚举L~R中所有的数,能否被P整除

代码如下
#include <cstdio>
#include <cmath>
#include <vector>
#include <cstring>
using namespace std;
#define ll long long
const ll MAXN = 1e7 + 5;
vector<ll> zs;
bool f[MAXN];
ll ans1, ans2, ans3, ans4, maxn, minn;
ll l, r, size;
void Sqrt_R() {
ll i, j;
f[1] = 1;
size = 0;
zs.clear();
for (i = 2; i <= sqrt(r); i++) {
if (f[i])
continue;
zs.push_back(i);
for (j = 1; j <= sqrt(r) / i; j++) f[i * j] = 1;
}
}
void Prime_Number() {
ll i, j;
ll last, l1, cnt = 0;
minn = 0x3f3f3f3f;
maxn = -minn;
for (i = l; i <= r; i++) {
bool flag = 0;
for (vector<ll>::iterator it = zs.begin(); it != zs.end(); it++) {
if (i % (*it) == 0) {
flag = 1;
break;
}
}
if (i >= 2 && i <= sqrt(r))
if (flag && (!f[i]))
continue;
if (flag && (!(i >= 2 && i <= sqrt(r))))
continue;
cnt++;
if (cnt >= 2) {
ll min1 = i - last;
if (min1 < minn) {
ans1 = l1;
ans2 = i;
minn = min1;
}
ll max1 = i - last;
if (max1 > maxn) {
ans3 = l1;
ans4 = i;
maxn = max1;
}
}
last = i;
l1 = i;
}
if (cnt >= 2)
printf("%lld,%lld are closest, %lld,%lld are most distant.\n", ans1, ans2, ans3, ans4);
else
printf("There are no adjacent primes.\n");
}
int main() {
while (scanf("%lld %lld", &l, &r) != EOF) {
memset(f, 0, sizeof(f));
Sqrt_R();
Prime_Number();
}
return 0;
}

这种的时间复杂度是O((L-R)*sqrt( R)),于是,我超时了。



于是在上述方法的改进下,在找p的时候,把[L,R]中能整除p的数标记了,时间复杂度就可以减少到O(L-R),就不会超时。

正解
#include <cstdio>
#include <cmath>
#include <vector>
#include <cstring>
using namespace std;
#define ll long long
const ll MAXN = 1e7 + 5;
bool f[MAXN], p[MAXN];
ll ans1, ans2, ans3, ans4, maxn, minn;
ll l, r;
void Sqrt_R() {
ll i, j;
f[1] = 1;
for (i = 2; i <= sqrt(r); i++) {
if (f[i])
continue;
ll u = (l - 1) / i + 1;
while ((u * i) < l) u++;
if (u < 2)
u = 2;
while ((u * i) <= r) {
p[(u * i) - l] = 1;
u++;
}
}
}
void Prime_Number() {
ll i, j;
ll last, l1, cnt = 0;
minn = 0x7fffffff;
maxn = -minn;
for (i = l; i <= r; i++) {
if (!p[i - l] && i != 1) {
if (i - last < minn && cnt != 0) {
minn = i - last;
ans1 = last;
ans2 = i;
}
if (i - last > maxn && cnt != 0) {
maxn = i - last;
ans3 = last;
ans4 = i;
}
last = i;
cnt++;
}
}
if (cnt >= 2)
printf("%lld,%lld are closest, %lld,%lld are most distant.\n", ans1, ans2, ans3, ans4);
else
printf("There are no adjacent primes.\n");
}
int main() {
while (scanf("%lld %lld", &l, &r) != EOF) {
memset(f, 0, sizeof(f));
memset(p, 0, sizeof(p));
Sqrt_R();
Prime_Number();
}
return 0;
}

这道题用了埃氏筛法的思想。

单独来看,筛选1-n中的质数,时间复杂度只有O(n*log(n)),是竞赛中最常用的质数筛法。

POJ2689 [质数距离] 题解的更多相关文章

  1. poj2689 Prime Distance题解报告

    题目戳这里 [题目大意] 给定一个区间[L,R],求区间内的质数相邻两个距离最大和最小的. [思路分析] 其实很简单呀,很明显可以看出来是数论题,有关于质数的知识. 要注意一下的就是L和R的数据范围都 ...

  2. AcWing 196. 质数距离(筛法+离散化)打卡

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

  3. 力扣(LeetCode)计数质数 个人题解

    统计所有小于非负整数 n 的质数的数量. 示例: 输入: 10 输出: 4 解释: 小于 10 的质数一共有 4 个, 它们是 2, 3, 5, 7 . 一般方法,也就是一般人都会用的,将数从2到它本 ...

  4. LOJ P10130 点的距离 题解

    这道题相当于倍增求LCA的板子,我们只要构建一棵树,然后距离就是x的深度+y的深度 - LCA(x,y)的深度: #include<iostream> #include<cstdio ...

  5. 洛谷 P2136 拉近距离 题解

    P2136 拉近距离 题目背景 我是源点,你是终点.我们之间有负权环. --小明 题目描述 在小明和小红的生活中,有N个关键的节点.有M个事件,记为一个三元组(Si,Ti,Wi),表示从节点Si有一个 ...

  6. 【JZOJ4725】质数序列 题解(数学)

    题目大意:质数序列是指这个序列中任意两个数的和均为质数.先给出一个序列${a_{n}}$,从中取出元素构成最长质数序列,问其长度并输出序列.若长度相同则求和最大的序列.保证答案唯一. -------- ...

  7. 洛谷 P1279 字串距离 题解

    每日一题 day24 打卡 Analysis 字符串+dp 仔细观察发现,对于f[i][j],它的值为以下三个值中的最小者: f[i-1][j]+k //a[i]对应空格 f[i][j-1]+k // ...

  8. AcWing P173 矩阵距离 题解

    Analysis 就是一个裸的广搜,每次从是1的点开始找就好啦~~~ #include<iostream> #include<cstdio> #include<cstri ...

  9. ACwing 196. 质数距离

    #include <bits/stdc++.h> using namespace std; , M = ; int v[M]; long long prime[N],prim[N]; ; ...

随机推荐

  1. 超简单的CDH6部署和体验(单机版)

    欢迎访问我的GitHub https://github.com/zq2599/blog_demos 内容:所有原创文章分类汇总及配套源码,涉及Java.Docker.Kubernetes.DevOPS ...

  2. DockerFile系统的学习

    1.背景 DockerFile定义:用来构建Docker镜像的文件,有脚本命令组成. 自定义镜像并运行步骤:编写dockerFile文件-->docker build为镜像-->docke ...

  3. spring boot:用rocketmq消息订阅实现删除购物车商品功能(spring boot 2.3.3)

    一,为什么要使用消息队列实现删除购物车商品功能? 消息队列主要用来处理不需要立刻返回结果的业务, 常见的例子: 用户在下单后,要清除原购物车中的商品, 这个处理过程不需要马上实现也不需要返回结果给用户 ...

  4. centos8使用systemd/systemctl管理系统/服务

    一,systemd的用途? Systemd 是 Linux 系统工具,用来启动守护进程,已成为大多数发行版的标准配置 Systemd 的优点是功能强大,使用方便, 缺点是体系庞大,非常复杂 在cent ...

  5. 第十八章 HTTPS介绍及实战演练

    一.HTTPS介绍 1.概述 为什么需要使用HTTPS,因为HTTP不安全,当我们使用http网站时,会遭到劫持和篡改,如果采用https协议,那么数据在传输过程中是加密的,所以黑客无法窃取或者篡改数 ...

  6. IDEA提示类注释的wrong tag警告的解决办法

    当创建一个类的时候,给类写上注释时,出现类似于"Wrong tag 'date' less... (Ctrl+F1)"这种警告,解决方式是: alt + enter -> a ...

  7. 理解 Android Binder 机制(一):驱动篇

    Binder的实现是比较复杂的,想要完全弄明白是怎么一回事,并不是一件容易的事情. 这里面牵涉到好几个层次,每一层都有一些模块和机制需要理解.这部分内容预计会分为三篇文章来讲解.本文是第一篇,首先会对 ...

  8. poj 2229 一道动态规划思维题

    http://poj.org/problem?id=2229 先把题目连接发上.题目的意思就是: 把n拆分为2的幂相加的形式,问有多少种拆分方法. 看了大佬的完全背包代码很久都没懂,就照着网上的写了动 ...

  9. B. Two Arrays 解析(思維)

    Codeforce 1417 B. Two Arrays 解析(思維) 今天我們來看看CF1417B 題目連結 題目 略,請直接看原題. 前言 a @copyright petjelinux 版權所有 ...

  10. 解放双手,不写SQL!一个开源mybatis神器

    什么是通用 Mapper? 它是一个可以方便的使用 Mybatis 进行单表的增删改查优秀开源产品.它使用拦截器来实现具体的执行 Sql,完全使用原生的 Mybatis 进行操作.在 Github 上 ...