• 素数相关【转】


    1-n之间有多少个素数

    10的1次方        4
    10的2次方        25
    10的3次方        168
    10的4次方        1229
    10的5次方        9592
    10的6次方        78498
    10的7次方        664579
    10的8次方        5761455
    10的9次方        50847534

    1、单独判断一个数是否为素数

    1 bool prime(int n)  
    2 {  
    3     if(n==0||n==1) return false;  
    4     if(n==2) return true;  
    5     for(int i=2;i<=sqrt(n);i++)  
    6         if(n%i==0)  
    7             return false;  
    8     return true;  
    9 }  
    单独判断一个数是否为素数

    2、筛法筛素数 ,求小于maxn的素数

    isprime[ ] 保存小于maxn的数是否为素数,false表示不是素数,true表示素数

    prime[ ] 保存小于maxn的素数有哪些,从0开始,长度为len

     1 const int maxn=100;  
     2 bool isprime[maxn];  
     3 int prime[maxn];  
     4 int len=0;  
     5   
     6 void sieve(int n)  
     7 {  
     8     for(int i=0;i<n;i++)  
     9         isprime[i]=1;  
    10     isprime[0]=isprime[1]=0;  
    11     for(int i=2;i<n;i++)  
    12         if(isprime[i])  
    13         {  
    14             prime[len++]=i;  
    15             for(int j=2*i;j<n;j+=i)  
    16                 isprime[j]=0;  
    17         }  
    18 }  
    19 //主函数调用sieve(maxn)  
    筛法求素数

    3、如果只要求小于maxn的素数有哪些,去掉isprime[ ]数组

    下面模板中 prime[ ] 中保存的是maxn中的素数有哪些,标号从1开始,总的素数个数为prime[0] ,它包含的素数范围为 prime[1]到prime[  prime[0] ] 

     1 const int maxn=100;  
     2 int prime[maxn+1];  
     3   
     4 void getPrime()  
     5 {  
     6     memset(prime,0,sizeof(prime));//一开始prime都设为0代表都是素数(反向思考)  
     7     for(int i=2;i<=maxn;i++)  
     8     {  
     9         if(!prime[i])  
    10             prime[++prime[0]]=i;  
    11         for(int j=1;j<=prime[0]&&prime[j]<=maxn/i;j++)  
    12         {  
    13             prime[prime[j]*i]=1;//prime[k]=1;k不是素数  
    14             if(i%prime[j]==0)  
    15                 break;  
    16         }  
    17     }  
    18 }  
    rt

    4、大区间筛素数

    POJ:2689 

    给出一个区间[L,R], 范围为1<=L< R<=2147483647,区间长度长度不超过1000000

    求距离最近和最远的两个素数(也就是相邻的差最小和最大的素数)

    筛两次,第一次筛出1到1000000的素数,因为1000000^2已经超出int范围,这样的素数足够了。

    函数getPrim();   prime[ ] 存第一次筛出的素数,总个数为prime[0] 

    第二次利用已经筛出的素数去筛L,R之间的素数

    函数getPrime2();     isprime[] 判断该数是否为素数 prime2[ ]筛出的素数有哪些,一共有prime2[0]个

    模板:

     1 #include <iostream>
     2 #include <string.h>
     3 #include <stdio.h>
     4 #include <cmath>
     5 #include <algorithm>
     6 using namespace std;
     7 
     8 const int maxn=1e6;
     9 int prime[maxn+10];
    10 
    11 void getPrime()
    12 {
    13     memset(prime,0,sizeof(prime));//一开始prime都设为0代表都是素数(反向思考)
    14     for(int i=2;i<=maxn;i++)
    15     {
    16         if(!prime[i])
    17             prime[++prime[0]]=i;
    18         for(int j=1;j<=prime[0]&&prime[j]<=maxn/i;j++)
    19         {
    20             prime[prime[j]*i]=1;//prime[k]=1;k不是素数
    21             if(i%prime[j]==0)
    22                 break;
    23         }
    24     }
    25 }
    26 
    27 bool isprime[maxn+10];
    28 int prime2[maxn+10];
    29 
    30 void getPrime2(int L,int R)
    31 {
    32     memset(isprime,1,sizeof(isprime));
    33     //isprime[0]=isprime[1]=0;//这句话不能加,考虑到左区间为2的时候,加上这一句,素数2,3会被判成合数
    34     if(L<2) L=2;
    35     for(int i=1;i<=prime[0]&&(long long)prime[i]*prime[i]<=R;i++)
    36     {
    37         int s=L/prime[i]+(L%prime[i]>0);//计算第一个比L大且能被prime[i]整除的数是prime[i]的几倍,从此处开始筛
    38         if(s==1)//很特殊,如果从1开始筛的话,那么2会被筛成非素数
    39             s=2;
    40         for(int j=s;(long long)j*prime[i]<=R;j++)
    41             if((long long)j*prime[i]>=L)
    42             isprime[j*prime[i]-L]=false; //区间映射 ,比如区间长度为4的区间[4,7],映射到[0,3]中,因为题目范围2,147,483,647数组开不出来
    43     }
    44     prime2[0]=0;
    45     for(int i=0;i<=R-L;i++)
    46         if(isprime[i])
    47         prime2[++prime2[0]]=i+L;
    48 }
    49 
    50 int main()
    51 {
    52     getPrime();
    53     int L,R;
    54     while(scanf("%d%d",&L,&R)!=EOF)
    55     {
    56         getPrime2(L,R);
    57         if(prime2[0]<2)
    58             printf("There are no adjacent primes.
    ");
    59         else
    60         {
    61             //for(int i=1;i<=prime2[0];i++)
    62                // cout<<prime2[i]<<endl;
    63             int x1=0,x2=1000000,y1=0,y2=0;
    64             for(int i=1;i<prime2[0];i++)
    65             {
    66                 if(prime2[i+1]-prime2[i]<x2-x1)
    67                 {
    68                     x1=prime2[i];
    69                     x2=prime2[i+1];
    70                 }
    71                 if(prime2[i+1]-prime2[i]>y2-y1)
    72                 {
    73                     y1=prime2[i];
    74                     y2=prime2[i+1];
    75                 }
    76             }
    77             printf("%d,%d are closest, %d,%d are most distant.
    ",x1,x2,y1,y2);
    78         }
    79     }
    80     return 0;
    81 }
    View Code
    まだまだだね
  • 相关阅读:
    LeetCode-1370 Increasing Decreasing String
    LeetCode-1221 Split a String in Balanced Strings
    Neo4j 实战(三)-- Neo4j Loads CSV Files
    Neo4j 实战(二)-- neo4j 基础语句
    Java HashMap 学习笔记
    Markdown 入门笔记
    《知识图谱方法、实践与应用》读书笔记(第一遍)
    Java 数组复制
    LeetCode-496 Next Greater Element I Solution(with Java)
    linux 同步IO: sync、fsync与fdatasync
  • 原文地址:https://www.cnblogs.com/xxQ-1999/p/7500271.html
Copyright © 2020-2023  润新知