zoukankan      html  css  js  c++  java
  • POJ 2689 筛法求素数

    DES:给出一个区间[L, U]。找出这个区间内相邻的距离最近的两个素数和距离最远的两个素数。其中1<=L<U<=2147483647 区间长度不超过1000000.

    思路:因为给出的U的范围超出了int的最大。所以不能直接打出1-U的素数表。【我们知道。利用素数筛法时是把所有的合数都筛掉了。那么我们也想办法把L-U内的合数都筛掉就可以了。那么只要用sqrt(U)内的素数去筛掉L-U的合数就可以了。】只是大概理解。。。。。。。

     1 #include <stdio.h>
     2 #include <iostream>
     3 #include <string.h>
     4 #include <iostream>
     5 using namespace std;
     6 
     7 #define N 500000
     8 #define len 10000000
     9 #define inf 0x7fffffff
    10 bool isprime[N+5];
    11 long long prime[N], cnt;
    12 bool res[len+5];
    13 
    14 void init() { // 筛选50000内的素数。要注意i比较大时 会容易超int的范围
    15      long long i, j;
    16      cnt = 0;
    17      memset(isprime, true, sizeof(isprime));
    18      for (i=2; i<=N; ++i) {
    19         if (isprime[i]) {
    20             prime[cnt++] = i;
    21             if (i*i <= N) {
    22                 for (j=i*i; j<=N; j+=i) {
    23                     isprime[j] = false;
    24                 }
    25             }
    26         }
    27      }
    28 }
    29 
    30 int main() {
    31     long long L, U, i, j, k, minn, maxx, s, t;
    32     init();
    33     while(~scanf("%lld%lld", &L, &U)) {
    34         memset(res, 0, sizeof(res));
    35         for (i=0; i<cnt; ++i) {
    36             s = (L-1)/prime[i]+1;  // s和t表示了当前范围里的数对这个素数的最小倍数和最大倍数。 比如说 区间[3, 9] 对素数2 的 s 和 t 应是 2, 4
    37             t = U/prime[i];   // 由这个例子可以知道为什么 L-1 最后再+1。t就可以直接除。
    38             for (j=s; j<=t; ++j) { // 筛选出区间内的素数
    39                 if (j>1) { // 不知道为什么==1的时候也不算?????
    40                     res[j*prime[i]-L] = true;
    41                 }
    42             }
    43         }
    44         k = -1, minn = inf, maxx = -1;
    45         long long dis, m1, m2;
    46         for (i=0; i<=U-L; ++i) { // 求解最优值
    47             if (!res[i]) {
    48                 if (k!=-1) {
    49                     dis=i-k;  // 记录两个素数的最远距离。
    50                     if (dis > maxx) {
    51                         maxx = dis;
    52                         m1 = i;
    53                     }
    54                     if (dis < minn) {
    55                         minn = dis;
    56                         m2 = i;
    57                     }
    58                 }
    59                 if (i+L != 1) // 注意1 的时候特殊判断1不是素数。
    60                     k=i;
    61             }
    62         }
    63         if (maxx == -1)
    64             printf("There are no adjacent primes.
    ");
    65         else printf("%lld,%lld are closest, %lld,%lld are most distant.
    ", m2-minn+L, m2+L, m1-maxx+L, m1+L);
    66     }
    67     return 0;
    68 }
    View Code

    代码可以理解。裸敲好像。。。还是有一点难度。明天再敲一遍。

  • 相关阅读:
    关于jquery判断对象是否为空
    php设计模式学习之观察者模式
    php设计模式学习之单例模式
    Nginx+phpfastcgi下flush输出问题
    php设计模式学习之工厂模式
    centos设置ssh免密码登陆
    关于yii2自带验证码功能不显示问题
    html原样输出html代码
    centos7安装iptables
    centos下配置nginx支持php
  • 原文地址:https://www.cnblogs.com/icode-girl/p/4868122.html
Copyright © 2011-2022 走看看