POJ 2689.Prime Distance-区间筛素数
最近改自己的错误代码改到要上天,心累。
这是迄今为止写的最心累的博客。
| Time Limit: 1000MS | Memory Limit: 65536K | |
| Total Submissions: 18707 | Accepted: 4998 |
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.
题意就是找给定的区间内距离最近的两个素数和距离最远的两个素数。
因为给的数很大,不能从(1-U)筛素数,这样写会re,我是智障,我一开始从1到U开始筛的素数,被T飞了,
想着自己好不容易改了个筛选法求欧拉函数的代码(改的这个代码,传送门:http://www.cnblogs.com/ZERO-/p/6582239.html)写这道题,就一直坚持不懈的改。
样例可以过啊,交上就不可以。后来越改越不靠谱,Memory Limit Exceeded,Runtime Error。。。
这才反应过来是自己的代码写的有问题,要换思路。因为给的数很大,所以从头开始筛素数是不可以的,空间上不允许,所以才MLE。。。
然后就看了一下区间筛素数,把人家求区间有几个素数的代码拿来改(传送门:http://www.cnblogs.com/nowandforever/p/4515612.html),改的我头大,但好在最后a了,唉,心累啊。
人家的题目代码:
给定整数a和b,请问区间[a,b)内有多少个素数?
a<b<=10^12
b-a<=10^6
因为b以内合数的最小质因数一定不超过sqrt(b),如果有sqrt(b)以内的素数表的话,就可以把筛选法用在[a,b)上了,先分别做好[2,sqrt(b))的表和[a,b)的表,然后从[2,sqrt(b))的表中筛得素数的同时,也将其倍数从[a,b)的表中划去,最后剩下的就是区间[a,b)内的素数了。
有的时候需要求出某个特定区间的素数,但是数可能很大,数组也开不小,所以需要进行下标偏移,这样才可以使用筛选法。

区间素数统计代码:
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
typedef long long ll;
const int maxn=1e6+;
bool is_prime[maxn];
bool is_prime_small[maxn];
ll prime[maxn];
ll prime_num=;
void segment_sieve(ll a,ll b){
for(ll i=;i*i<b;++i) is_prime_small[i]=true;
for(ll i=;i<b-a;++i) is_prime[i]=true;
for(ll i=;i*i<b;++i){
if(is_prime_small[i]){
for(ll j=*i;j*j<b;j+=i) is_prime_small[j]=false;
for(ll j=max(2LL,(a+i-)/i)*i;j<b;j+=i) is_prime[j-a]=false;
}
}
for(ll i=;i<b-a;++i)
if(is_prime[i]) prime[prime_num++]=i+a;
}
int main(){
ll a,b;
while(~scanf("%lld%lld",&a,&b)){
prime_num=;
memset(prime,,sizeof(prime));
segment_sieve(a,b);
printf("%lld\n",prime_num);
}
return ;
}
好好理解了人家的代码之后就开始进行改造了。
人家的代码写的是有下标偏移量的,所以后来把素数找出来的时候要再加回去,就是i+n;
然后就是将距离最近的值和距离最远的值找出来,然后再通过距离值找出来素数,应该有直接就可以将素数找出来的,无奈,我太菜,只会这样写。。。
因为人家是求的[a,b)区间的素数个数,所以我改的时候就写的a,b+1,这样求的就是[a,b]闭区间的素数,然后就是人家的代码没有将1这个既不是素数也不是合数的家伙去掉,所以加了个判断。
自己的垃圾代码:
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
typedef long long ll;
const int N=1e6+;
const ll INF=0x3f3f3f3f;
bool prime1[N];
bool prime2[N];
ll ss[N];
ll num=;
void findprime(ll n,ll m){ //区间筛素数,筛的是从[n,m)的,下面传的参数是n,m+1,所以保证是求的闭区间的。好好想想。
for(ll i=;i*i<m;i++) prime1[i]=true; //这是对[2,sqrt(m))的初始化。
for(ll i=;i<m-n;i++) prime2[i]=true; //对下标偏移之后的[n,m)进行初始化。
for(ll i=;i*i<m;i++){
if(prime1[i]){
for(ll j=*i;j*j<m;j+=i) prime1[j]=false; //找出来[2,sqrt(m))中不是素数的筛出去。
for(ll j=max((ll),(n+i-)/i)*i;j<m;j+=i) prime2[j-n]=false; //将偏移后的[n,m)中的不是素数的筛出去。
} //j=max((ll)2,(n+i-1)/i)*i;j<m;j+=i)意思就是从最接近n的数开始,将那些合数的倍数,从2倍开始,筛掉。
}
}
int main(){
ll n,m,h;
ll minn,maxx;
while(~scanf("%lld%lld",&n,&m)){
memset(prime2,,sizeof(prime2));
memset(ss,,sizeof(ss));
findprime(n,m+); //这样保证是求的[n,m]这个闭区间的
h=;
for(int i=;i<m-n+;i++){
if(prime2[i]&&i+n!=)//如果是true就是成立的,因为上面区间筛素数没有筛掉1(既不是素数也不是合数),所以判断一下。
ss[h++]=i+n; //将下标偏移量再加回来。
}
if(h<) printf("There are no adjacent primes.\n"); //保证必须有>=2个素数。
else{
minn=INF;maxx=-;
for(int i=;i<h-;i++){ //我太菜,只会这样找。
minn=min(minn,ss[i+]-ss[i]); //找出距离最近的值是多少。
maxx=max(maxx,ss[i+]-ss[i]); //找出距离最远的值是多少。
}
for(int i=;i<h-;i++){
if(ss[i+]-ss[i]==minn){ //将距离最近的2个素数找出来,输出来最先找到的一组就可以。
printf("%lld,%lld are closest, ",ss[i],ss[i+]);
break;
}
}
for(int i=;i<h-;i++){ //意思同上。
if(ss[i+]-ss[i]==maxx){
printf("%lld,%lld are most distant.\n",ss[i],ss[i+]);
break;
}
}
}
}
return ;
}
改代码改的好辛苦,因为太菜了,人家补题的时间,我就只能自己一个人怀疑人生般的debug。。。
改了20多遍,我也是菜的可怜。。。
筛选法求欧拉函数的代码也能让我改成从2开始到n筛素数的代码,感觉自己也是没谁了,呵呵哒。
这就是现实,自己满心欢喜的改自己好不容易写出来的代码,最后也是不可以,那就放弃换一个思路吧。总得做点什么,要不怎么都a不了这道题。
反省深刻,继续努力,菜的掉渣,咸鱼,加油哦。唉:-(
剩下的题解等把所有的题都补完了再来写。
POJ 2689.Prime Distance-区间筛素数的更多相关文章
- 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 Time Limit: 1000MS Memory Limit: 65536K Description The branch o ...
- poj 2689 Prime Distance(大区间素数)
题目链接:poj 2689 Prime Distance 题意: 给你一个很大的区间(区间差不超过100w),让你找出这个区间的相邻最大和最小的两对素数 题解: 正向去找这个区间的素数会超时,我们考虑 ...
- poj 2689 Prime Distance (素数二次筛法)
2689 -- Prime Distance 没怎么研究过数论,还是今天才知道有素数二次筛法这样的东西. 题意是,要求求出给定区间内相邻两个素数的最大和最小差. 二次筛法的意思其实就是先将1~sqrt ...
- 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 ...
- 题解报告:poj 2689 Prime Distance(区间素数筛)
Description The branch of mathematics called number theory is about properties of numbers. One of th ...
随机推荐
- Visual Studio使用技巧笔记(引用程序集自动复制dll到引用项目目录)
copy /y $(TargetPath) $(SolutionDir)\[您项目引用dll文件的目录]\$(TargetFileName) 例如:copy /y $(TargetPath) $(So ...
- Python全栈 MySQL 数据库 (简述 、安装、基本命令)
ParisGabriel 每天坚持手写 一天一篇 决定坚持几年 为了梦想为了信仰 开局一张图 一个月的python已经结束了 下面就是数据库了 先说M ...
- A. Vasya and Book
题目原址 http://codeforces.com/contest/1082/problem/A 题目内容 一共n页书,现在位于第x位,想要看第y页,每次只能翻d页,注意总能翻到第1页和第n页. V ...
- PAT——甲级1046S:shortest Distance
这道题,折磨了我一个多小时,前前后后写了三个算法. 1046 Shortest Distance (20 point(s)) The task is really simple: given N ex ...
- React跨域问题解决
https://segmentfault.com/q/1010000012732581 非跨域问题报错 -rpccorsdomain="http://localhost:3000" ...
- shell之ip命令
转:出处我也不知道了,学习时候记下的笔记 1.作用 ip是iproute2软件包里面的一个强大的网络配置工具,它能够替代一些传统的网络管理工具,例如ifconfig.route等,使用权限为超级用户. ...
- Spring Web MVC 笔记
Spring Web MVC 流程 Dispatcher Servlet 这是一个前端分派 Servlet(前端控制器模式),外部所有的请求都会先到达这里,然后由其将请求分派给其他组件进行实际的处理. ...
- ASP.NET——真假分页
所谓分页,就是把所有要显示的内容分成n多页来显示.那为什么要用分页而不直接全部显示呢?这就好比一本书,我们可以用一张纸写完全部书的内容,但实际上并不是这么做的.我们把网页分成一页一页的,其实很大程度上 ...
- task [最大权闭合子图]
题面 思路 其实仔细读透就发现,是一个最大权闭合子图的模型 套进网络流里面就挺好做的了 可以选择重载这道题里面的一些运算(加减,取最小值),这样比较方便 Code #include<iostre ...
- [中山市选2011][bzoj2440] 完全平方数 [二分+莫比乌斯容斥]
题面 传送门 思路 新姿势get 莫比乌斯容斥 $\sum_{i=1}{n}\mu(i)f(i)$ 这个东西可以把所有没有平方质因子的东西表示出来,还能容斥掉重复的项 证明是根据莫比乌斯函数的定义,显 ...