poj Prime Distance(暴力 二次筛法)
2014-05-17 21:35
309 查看
此题数据范围灰常大,输入范围高达int的最大值,故素数是不可能全部保存下来的。。借此机会学习了二次筛法,其实就是用n里面的所有合数可以被sqet(n)里面所有质数给筛掉的原理,故只需要先筛出2^16次方以下的素数就可以了,一直用的是最普通的筛法,找时间去学学线性筛法。。。筛完后,看输入进来的a,b,如果b小于2^16那就直接复制原来素数表里的,如果不是,就要通过素数表里的素数来筛了,具体方法是从第一个素数p开始,乘以大于等于a的最小值k,再在标记数组里标记(p*k-a)为1,k++,重复操作直到b为止。这样的好处在于标记数组是从0到b-a的就不会浪费空间,因为范围实在太大开不了2^32次方的数组,在下面找素数的时候第i位置标记是0,说明是素数就可以用i+a来得到素数的值。
还需要正确估计素数的多少,就要用到一个公式n个连续的数,素数的个数大概n/ln(n)。这个公式得出来的值n越大越精确。
AC代码:
还需要正确估计素数的多少,就要用到一个公式n个连续的数,素数的个数大概n/ln(n)。这个公式得出来的值n越大越精确。
AC代码:
#include<cstdio> #include<ctype.h> #include<algorithm> #include<iostream> #include<cstring> #include<vector> #include<stack> #include<cmath> #include<queue> #include<set> #include<ctime> using namespace std; #define NMAX 50000 #define ll long long bool mark[1000010]; int prime[7000],pp[80000]; int pprime() { int i,j,k,m = NMAX; for(i = 2; i*i < m; i++) { for(j = i*i; j < m; j+=i) mark[j] = true; } for(k = 0,i = 2; i < m; i++) if(!mark[i]) prime[k++] = i; return k; } int main() { // freopen("input.txt","r",stdin); // freopen("o1.txt","w",stdout); int n = pprime(); int a,b,i,j,k; while(~scanf("%d %d",&a,&b)) { int e,fmin,fmax,n2=0; memset(mark,0,sizeof(mark)); if(b <= NMAX) { for(i = 0; prime[i] < a; i++); for(n2 = 0; prime[i] <= b;) pp[n2++] = prime[i++]; } else { for(i = 0; i < n && prime[i]*prime[i] <= b; i++) { if(prime[i] >= a) k = 2; else { k = a/prime[i]; if(prime[i]%2) k++; } while(k <= b/prime[i])//这里本来写的是k*prime[i]<b。但是会超int范围就改成除法了 { mark[k*prime[i]-a] = 1; k++; } } for(i = 0; i <= b-a; i++) if(!mark[i]) pp[n2++] = i+a; } e = n2; if(e <= 1) printf("There are no adjacent primes.\n"); else { int Min=1000000,Max=0; for(i = e-1; i > 0; i--) { int temp = pp[i] - pp[i-1]; if(temp >= Max) { fmax = i-1; Max = temp; } if(temp <= Min) { fmin = i-1; Min = temp; } } printf("%d,%d are closest, %d,%d are most distant.\n",pp[fmin],pp[fmin+1],pp[fmax],pp[fmax+1]); } } return 0; }
相关文章推荐
- poj 2689 Prime Distance (素数二次筛法)
- poj 2689 Prime Distance 筛法/二次筛法/区间素数
- poj 2689 Prime Distance 二次筛法,找出给定区间所有约数
- poj 2689 Prime Distance 二次筛法,找出给定区间所有约数
- poj 2689 Prime Distance 二次筛法,找出给定区间所有约数
- poj 2689 Prime Distance 二次筛法
- poj2689 Prime Distance 有难度 埃拉托斯尼斯筛法的运用
- poj 2689 Prime Distance 二次筛素数
- POJ 2689 Prime Distance 二次筛选
- POJ 2689 Prime Distance (二次?筛素数)
- POJ 2689 Prime Distance【大区间素数筛选】【埃氏筛法】【经典题】
- POJ - 2689 Prime Distance(2次用筛法)
- Poj 2689 Prime Distance(素数筛+二次素数筛)
- POJ 2689 Prime Distance [筛法选取素数]【数论】
- POJ 2689 Prime Distance(大区间素数筛法,两次筛法)
- POJ 2689 Prime Distance(筛法)
- [数论] POJ 2689 Prime Distance 二次筛选
- POJ-2689-Prime Distance(筛法)
- POJ 2689 Prime Distance(素数区间筛法--经典题)
- poj 2689 Prime Distance 筛法+区间筛素数