题解报告:poj 2689 Prime Distance(区间素数筛)
Description
Your program is given 2 numbers: L and U (1<=L< U<=2,147,483,647), and you are to find the two adjacent primes C1 and C2 (L<=C1< C2<=U) that are closest (i.e. C2-C1 is the minimum). If there are other pairs that are the same distance apart, use the first pair. You are also to find the two adjacent primes D1 and D2 (L<=D1< D2<=U) where D1 and D2 are as distant from each other as possible (again choosing the first pair if there is a tie).
Input
Output
Sample Input
2 17
14 17
Sample Output
2,3 are closest, 7,11 are most distant.
There are no adjacent primes.
解题思路:题目的意思就是给出区间[L,U],要求分别找出最近距离、最远距离的一对相邻素数,其中区间[L,U]长度不超过1e6,且L,U∈[1,2147483647]。由于L,U允许有最大值,而在堆区数组也开不了这么大的内存,所以应该考虑区间筛法。由埃氏筛的定义可知:通过枚举不大于sqrt(n)内的所有素数,将素数的倍数一一筛掉,最后剩下的都是素数。利用这个特点,我们可以先做好[2,sqrt(U)]的素数表,然后从[2,sqrt(U)]的表中筛得素数的同时,也将其倍数从[L,U]的表中划去(这里由于开不了很大的数组,所以区间[L,R]中每个值即下标整体向左偏移了L个单位,这样就够标记区间长达1e6个元素了,详解看代码),那么最后剩下的就是区间[L,U]内的素数了。注意:必须特判L,因为题目中要求输出相邻一对素数之间的距离,前提必须是素数,而1不是素数,所以区间左端点值最小为2。
AC代码:
#include<iostream>
#include<string.h>
#include<algorithm>
#include<cstdio>
using namespace std;
typedef long long LL;
const int maxn=1e6+;
LL L,U,prime[maxn];bool isp1[maxn],isp2[maxn];
int segment_sieve(LL L,LL R){//区间筛法
memset(isp1,true,sizeof(isp1));//isp1标记[2,sqrt(R)]内的素数
memset(isp2,true,sizeof(isp2));//isp2标记区间[L,R]中的素数,其中isp2[j-L]=true <=> j是素数
if(L<)L=;//注意左端点必须是从2开始,必须特判这种情况
for(LL i=;i*i<=R;++i){//枚举不大于sqrt(R)即可(埃氏筛)
if(isp1[i]){
for(LL j=i*i;j*j<=R;j+=i)isp1[j]=false;//筛[2,sqrt(R)],选出这个区间的所有素数,然后去筛掉区间[L,R]的所有合数
for(LL j=max(2LL,(L+i-)/i)*i;j<=R;j+=i)isp2[j-L]=false;
//(L+i-1)/i得到最接近L的i的倍数,最小是i的2倍,然后筛掉区间[L,R]中素数i的倍数(合数)
}
}
int cnt=;//记录区间[L,R]中素数的个数
for(LL i=;i<=R-L;++i)//0~R-L
if(isp2[i])prime[cnt++]=i+L;//保存区间[L,R]中的所有素数
return cnt;
}
int main(){
while(~scanf("%lld%lld",&L,&U)){
int num=segment_sieve(L,U);
if(num<)printf("There are no adjacent primes.\n");//如果个数小于2,说明没有相邻的素数,直接输出
else{//依次去枚举区间[L,U]中所有相邻素数的距离
LL mlt=,mrt=,nlt=,nrt=,f1=,f2=maxn;
for(int i=;i<num;++i){
if(prime[i]-prime[i-]>f1)//最远距离的一对相邻素数
f1=prime[i]-prime[i-],mlt=prime[i-],mrt=prime[i];
if(prime[i]-prime[i-]<f2)//最近距离的一对相邻素数
f2=prime[i]-prime[i-],nlt=prime[i-],nrt=prime[i];
}
printf("%lld,%lld are closest, %lld,%lld are most distant.\n",nlt,nrt,mlt,mrt);
}
}
return ;
}
题解报告:poj 2689 Prime Distance(区间素数筛)的更多相关文章
- poj 2689 Prime Distance (素数二次筛法)
2689 -- Prime Distance 没怎么研究过数论,还是今天才知道有素数二次筛法这样的东西. 题意是,要求求出给定区间内相邻两个素数的最大和最小差. 二次筛法的意思其实就是先将1~sqrt ...
- POJ 2689 Prime Distance (素数筛选法,大区间筛选)
题意:给出一个区间[L,U],找出区间里相邻的距离最近的两个素数和距离最远的两个素数. 用素数筛选法.所有小于U的数,如果是合数,必定是某个因子(2到sqrt(U)间的素数)的倍数.由于sqrt(U) ...
- poj 2689 Prime Distance(区间筛选素数)
Prime Distance Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 9944 Accepted: 2677 De ...
- POJ - 2689 Prime Distance (区间筛)
题意:求[L,R]中差值最小和最大的相邻素数(区间长度不超过1e6). 由于非素数$n$必然能被一个不超过$\sqrt n$的素数筛掉,因此首先筛出$[1,\sqrt R]$中的全部素数,然后用这些素 ...
- POJ 2689 Prime Distance (素数+两次筛选)
题目地址:http://poj.org/problem?id=2689 题意:给你一个不超过1000000的区间L-R,要你求出区间内相邻素数差的最大最小值,输出相邻素数. AC代码: #includ ...
- POJ 2689 Prime Distance(素数筛选)
题目链接:http://poj.org/problem?id=2689 题意:给出一个区间[L, R],找出区间内相连的,距离最近和距离最远的两个素数对.其中(1<=L<R<=2,1 ...
- poj 2689 Prime Distance(大区间素数)
题目链接:poj 2689 Prime Distance 题意: 给你一个很大的区间(区间差不超过100w),让你找出这个区间的相邻最大和最小的两对素数 题解: 正向去找这个区间的素数会超时,我们考虑 ...
- poj 2689 Prime Distance(大区间筛素数)
http://poj.org/problem?id=2689 题意:给出一个大区间[L,U],分别求出该区间内连续的相差最小和相差最大的素数对. 由于L<U<=2147483647,直接筛 ...
- [ACM] POJ 2689 Prime Distance (筛选范围大素数)
Prime Distance Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 12811 Accepted: 3420 D ...
- 数论 - 素数的运用 --- poj 2689 : Prime Distance
Prime Distance Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 12512 Accepted: 3340 D ...
随机推荐
- Delphi中匿名方法动态绑定事件
应恢弘之约,写了一个对其发布的匿名函数动态绑定到事件的封装,代码如下: type TAnonEvent=class public class function Wrap<T1,T2>(On ...
- Capture and report JavaScript errors with window.onerror
原文:https://blog.sentry.io/2016/01/04/client-javascript-reporting-window-onerror.html onerror is a sp ...
- centos7备份还原与grub2引导和rescue模式修改root密码
一.centos7备份1.su -2.cd /3.tar -zpPcvf backup.tgz --exclude=/sys --exclude=/mnt --exclude=/proc --excl ...
- leetCode 67.Add Binary (二进制加法) 解题思路和方法
Given two binary strings, return their sum (also a binary string). For example, a = "11" b ...
- unix时间戳(unix timestamp)与北京时间的互转方法
1.在linux bash下北京时间与unix时间戳互转: 获取unix timestamp: 命令:date "+%s" 输出:1372654714 获取北京时间: 命令:dat ...
- Visual Studio 2017中使用正则修改部分内容 如何使用ILAsm与ILDasm修改.Net exe(dll)文件 C#学习-图解教程(1):格式化数字字符串 小程序开发之图片转Base64(C#、.Net) jquery遍历table为每一个单元格取值及赋值 。net加密解密相关方法 .net关于坐标之间一些简单操作
Visual Studio 2017中使用正则修改部分内容 最近在项目中想实现一个小工具,需要根据类的属性<summary>的内容加上相应的[Description]特性,需要实现的效 ...
- BZOJ 1122 POI2008 账本BBB 单调队列
题目大意:给定一个由+1和−1构成的长度为n的序列,提供两种操作: 1.将某一位取反,花销为x 2.将最后一位移动到前一位.花销为y 要求终于p+sumn=q.且p+sumi≥0(1≤i≤n),求最小 ...
- uml时序图的初印象-------Day64
近期有好多想法迫不及待的想去实现,但是其实是在那些最開始想的很明确,感觉会没问题的地方也总是会出现故障,导致稍微有些急躁,还是要淡定啊.又到了周末.明后天要收拾东西搬家,不知道宽带能不能顺利的给挪过去 ...
- C++ 函数部分(1)
1.编写一个求X的n次方的函数 .csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas ...
- linux input子系统 — TP A/B(Slot)协议【转】
本文转载自:http://blog.csdn.net/u012719256/article/details/53609906 将A/B协议这部分单独拿出来说一方面是因为这部分内容是比较容易忽视的,周围 ...