质数距离

质数距离

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

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

输入格式

每行输入两质数距离个整数 LU,其中 LU 的差值不会超过 106

输出格式

对于每个 LU,输出一个结果,结果占一行。

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

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

数据范围

1L<U2311

输入样例:

2 17
14 17

输出样例:

2,3 are closest, 7,11 are most distant.
There are no adjacent primes.

 

解题思路

  很容易想到先把所有的质数筛出来,对于每次询问遍历一遍区间范围内的质数就能够找到答案。但区间右端点最大可以取到109,因此不可能把所有的质数给筛出来。

  所有就容易想到说把区间[L,R]的质数筛出来,但目前筛质数的算法都是从2开始筛的,因此这种做法也行不通。

  本质就是找到区间[L,R]中的质数,现在质数不好找就看看能不能把所有的合数找出来。对于每个合数x都必然存在一个因子dx,这就启示我们可以先把所有小于2311的质数筛出来,然后枚举这些质数p,把[L,R]p的倍数(2倍以上,不可以是1倍否则就把质数p筛掉了)都筛掉。对于[L,R]内的合数x,由于必然存在一个不超过x的质因子p,因此当枚举到p时,由于px因此x会被筛掉。需要注意的是p要满足p<x,即要满足x至少是p2倍。

  其中,大于等于L的最小的p的倍数是Lp×p(补充,小于等于L的最大的p的倍数是Lp×p)。

  时间复杂度的计算,在[L,R]中,p的倍数最多有106p个,因此一共需要筛1062+1063+1065+1067++1062311106loglog(2311)=O(nloglogm)。时间复杂度的计算与埃式筛法很类似。

  AC代码如下:

复制代码
 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 
 4 typedef long long LL;
 5 
 6 const int N = 1e6 + 10;
 7 
 8 int primes[N], cnt;
 9 bool vis[N], st[N];
10 
11 void get_prime(int n) {
12     for (int i = 2; i <= n; i++) {
13         if (!vis[i]) primes[cnt++] = i;
14         for (int j = 0; primes[j] <= n / i; j++) {
15             vis[primes[j] * i] = true;
16             if (i % primes[j] == 0) break;
17         }
18     }
19 }
20 
21 int main() {
22     get_prime(47000);   // sqrt(2^31 - 1) < 47000
23     int l, r;
24     while (~scanf("%d %d", &l, &r)) {
25         memset(st, 0, sizeof(st));
26         for (int i = 0; i < cnt; i++) {
27             LL p = primes[i];   // 把[l, r]中p的数筛掉
28             LL t = max(2 * p, (l + p - 1) / p * p); // 大于等于l的最小的p的倍数(至少2倍)
29             while (t <= r) {
30                 st[t - l] = true;   // 由于t很大,因此减去一个偏移量,映射到10^6内
31                 t += p;
32             }
33         }
34         vector<int> p;
35         for (int i = 0; i <= r - l; i++) {  // 找到[l, r]内的所有质数
36             if (i + l >= 2 && !st[i]) p.push_back(i + l);
37         }
38         if (p.size() < 2) {
39             printf("There are no adjacent primes.\n");
40         }
41         else {
42             int a = 0, b = 0;
43             for (int i = 0; i + 1 < p.size(); i++) {
44                 if (p[i + 1] - p[i] < p[a + 1] - p[a]) a = i;
45                 if (p[i + 1] - p[i] > p[b + 1] - p[b]) b = i;
46             }
47             printf("%d,%d are closest, %d,%d are most distant.\n", p[a], p[a + 1], p[b], p[b + 1]);
48         }
49     }
50     
51     return 0;
52 }
复制代码

 

解题思路

  AcWing 196. 质数距离(算法提高课):https://www.acwing.com/video/681/

posted @   onlyblues  阅读(190)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 单线程的Redis速度为什么快?
· 展开说说关于C#中ORM框架的用法!
· Pantheons:用 TypeScript 打造主流大模型对话的一站式集成库
· SQL Server 2025 AI相关能力初探
· 为什么 退出登录 或 修改密码 无法使 token 失效
Web Analytics
点击右上角即可分享
微信分享提示