判断素数

素数判定的三种方法(cpp代码)

假如想象 提交于 2020-02-13 12:15:23
文章目录 一般方法 埃拉托斯特尼筛法(埃氏筛) 线性筛 一般方法 原理概述: 1不是质数也不是合数,特殊处理; 从2枚举到 √x,若有能除尽的数直接返回x不是素数 Q:为什么枚举到√x? 若m整除n(其中n>根号m)则m=n*k。 若m不整除从1除到√m的数它就不可能整除根号m后面的数。 如果根号m有小于√m的因子X,那么N必定有大于√m的因子Y与X对应。 而且X *Y=m (来源:百度) 实现说明: 略 bool isPrime_usual ( int x ) { if ( x == 1 ) return false ; for ( int i = 2 ; i * i <= x ; i ++ ) if ( x % i == 0 ) return false ; return true ; } 埃拉托斯特尼筛法(埃氏筛) 原理概述: 从最小的素数2开始,2…3…5…将这些数的倍数标为合数。 实现说明: 首先要有一个数组vis,用来标记那些数是素数,所得结果也存在这个数组,并都初始化为true(即默认所有数都是素数) 从2开始枚举,若vis[i]==true,则用一个循环去将vis[i]的倍数都标记为非素数。个人感受j从i * i开始好一些,有一些从j=2*i开始会降低效率(重复筛)。 bool vis [ Maxn ] ; void isPrinme_era ( ) {

程序二:素数

拥有回忆 提交于 2020-02-12 22:46:59
程序二 题目:判断101-200之间有多少个素数,并输出所有素数。 public class test02 { public static void main ( String [ ] args ) { int sum = 0 ; for ( int i = 100 ; i < 200 ; i ++ ) { if ( prime ( i ) ) { //判断这个数是不是素数 System . out . print ( i + " " ) ; sum ++ ; if ( sum % 5 == 0 ) { //五个一行 System . out . println ( ) ; } } } System . out . println ( ) ; System . out . println ( "素数的个数:" + sum ) ; } //判断这个数是不是素数的代码 private static boolean prime ( int i ) { for ( int j = 2 ; j <= Math . sqrt ( i ) ; j ++ ) { if ( i % j == 0 ) { //如果能整除,就说明不是素数,可以马上中断,继续对下一个数判断 return false ; } } return true ; } } 来源: CSDN 作者: Magine豪 链接:

sqrt()函数对素数判断的优化

点点圈 提交于 2020-02-12 21:00:15
素数是只有1和本身能整除的整数。所以在求素数的时候,要将素数与1到素数本身中间的所有整数都相除,看是否有整除的数,如果有,那肯定不是素数了。但是从算法上考虑,为了减少重复量,开平方后面的数就不用相除了,因为a/b(平方数)=c(小一点的数),同样a/c=b。举例说明: 25,开平方以后是5,那么整除2~5就可以了,如果有满足条件的,就是素数。 这样做可以减少循环次数,素数是因子为1和本身, 如果数c不是素数,则还有其他因子,其中的因子,假如为a,b. 其中必有一个大于sqrt(c) ,一个小于sqrt(c) 。 所以m必有一个小于或等于其 平方根 的因数,那么验证素数时就只需要验证到其平方根就可以了。即 一个合数一定含有小于它平方根的质因子。 再比如: 24的因数有1、2、3、4、6、8、12、24 按定义应该用2-23去除,但经过分析上面的数可以发现 1×24、2×12、3×8、4×6 如果2、3、4是某个数的因数,那么另外几个数也是,反之也一样 所以为提高效率,可以只检查小于该数平方根的那些数,如24的平方根大于4小于5,检查2-4就可以了! 来源: https://www.cnblogs.com/wcxcc/p/10410144.html

素数环

£可爱£侵袭症+ 提交于 2020-02-12 02:01:02
素数环 题目: 从1到20这20个数摆成一个环,要求相邻的两个数的和是一个素数。 ——————————下面开始解析————————— 这道题 是搜索与回溯的经典题 把两个数加起来 必须是素数 但是要注意 是环形 第20个和第1个也要算 也要注意一下 ——————————下面是伪代码详解—————————— 我们要 定义三个函数 search(int i) print() pd(int ss) 第一个是用来进行主运算 第二个是用来输出 第三个是用来判断函数 还要 定义两个数组 a[],b[] 一个用来保存 一个用来查看是否使用过 下面是核心代码: int search ( int j ) { int i ; for ( i = 1 ; i <= 20 ; i ++ ) //有20个数可选 { if ( 加在一起是素数并且没有用过 ) //判断与前一个数是否构成素数及该数是否可用 { a [ j ] = i ; b [ i ] = 1 ; if ( 可以输出 ) print ( ) ; else search ( t + 1 ) ; //递归 b [ i ] = 0 ; } } } 下面是大家 期待已久 的 代码 : # include <bits/stdc++.h> # include <iostream> # include <cstdlib> # include <cstdio>

各种招式筛素数

喜你入骨 提交于 2020-02-11 22:11:21
筛选素数方法归纳 我也不知道为什么突然好奇筛选素数,不过去查如何列举出n以内素数还是有一定原因的。有一天闲着没事干去翻了翻某佬的blog,看到有一道竞赛题是dp+筛选素数的,好奇之下就点了进去,dp思路看懂了,可这个筛素数愣是不知道什么原理,最后差不多琢磨一天才搞懂, (菜鸡警告~) 。 筛素数,这一听,感觉就挺简单的,傻瓜式(无脑)的解法就是写两个for循环,然后开始遍历,i%j是否可以为0,假如可以,说明不是素数,不展开讲这种我都能想得到的东西了. Code: #include<bits/stdc++.h> using namespace std; int prime[1000]; int main(){ int n,cnt=0,flag; memset(prime,0,sizeof(prime)); prime[++cnt]=2; scanf("%d",&n); for(int i=3;i<=n;i++) { flag=1; for(int j=2;j<i;j++)//可以把i换成sqrt(i); { if(i%j==0) flag=0; } if(flag==1) prime[++cnt]=i; } printf("%d\n",cnt); for(int i=1;i<=cnt;i++) printf("%d ",prime[i]); return 0; } 复杂度:O(n

[LOJ143]质数判定(Miller-rabin素数测试+防相乘爆long long的技巧讲解)

|▌冷眼眸甩不掉的悲伤 提交于 2020-02-09 20:47:14
题面 https://loj.ac/problem/143 题解 Miller-rabin素数测试 是一种随机化算法,能够在较短的时间内判断出一个数是合数,还是很可能为素数。其出错的概率极小;当用于测试的p取遍前10个素数时,在 \(3e18\) 的范围内不会出错。 原理:1、费马小定理 p为素数的必要不充分条件是 \(\forall (a,p)=1,a^{p-1}{\equiv}1{\mod p}\) 。证明不再赘述,可以参见百度百科或《数学奥林匹克命题人讲座:初等数论》2.3节。 2、二次探测 只使用费马小定理时,出错概率仍然较大,尤其是对于Carmichael数n(在 \(1e8\) 以下有255个,最著名的、最小的Carmichael数是561),对于所有的与n互质的正整数a,都可以满足 \(a^{n-1}{\equiv}1{\mod n}\) 。因此,仅仅使用Fermat测试是不够的。 二次探测的原理是:如果 \(x^2{\equiv}1{\mod p}\) ,p为素数,那么有 \(x{\equiv}{\pm}1{\mod p}\) 。证明显然,将1移项至左边,然后因式分解即可。 具体做法 设待测数为mod,若mod为偶数则可以直接判断。否则,我们将mod-1分解为 \(2^t*n\) ,其中 \(2{\nmid}n\) 。然后,取与mod互质的数p,计算 \[p^n、

hdu 2012 素数判定

风流意气都作罢 提交于 2020-02-08 02:40:15
素数判定 题目分析: 构造一个判断素数的函数fun,利用fun函数判断区间内的素数。 代码: #include <iostream> #include <math.h> #define fun(n) n*n + n + 41 using namespace std; int prime(int n) { if (n % 2 == 0) return 1; int end = sqrt(n), i; for (i = 3; i <= end; i += 2) { if (n % i == 0) break; } return i > end ? 0 : 1; } int main(void) { int x, y, i; while (cin>>x>>y) { if (x == 0 && y == 0) break; for (i = x; i <= y; i++) { if (prime(fun(i))) break; } if (i > y) printf("OK\n"); else printf("Sorry\n"); } return 0; } 来源: https://www.cnblogs.com/pcdl/p/12275366.html

素数之埃氏筛法&欧拉筛法

给你一囗甜甜゛ 提交于 2020-02-05 03:32:11
素数的判断   判断数n是否为一个素数,基本方法为从2开始向后枚举,若n不能被2,3,4,…,n-1整除,则n为素数,该判断方法的时间复杂度为 O ( n ) O(n) O ( n ) ;更快的方法为,当枚举至 n \sqrt n n ​ 时即可判断是否为素数,该判断方法的时间复杂度为 O ( n ) O(\sqrt n) O ( n ​ ) 。 代码如下: //写法1,其中sqrt函数位于头文件<math.h>,double sqrt(double a) bool isPrime ( int n ) { if ( n <= 1 ) return false ; //特判 int sqr = ( int ) sqrt ( 1.0 * n ) ; //根号n for ( int i = 2 ; i <= sqr ; i ++ ) { //遍历2~根号n if ( n % i == 0 ) return false ; } return true ; } //写法2,当n不接近int型上界时;或i以被定义为long long类型,不至于溢出 bool isPrime ( int n ) { if ( n <= 1 ) return false ; for ( int i = 2 ; i * i <= n ; i ++ ) { if ( n % i == 0 ) return false

PAT乙1007:素数对猜想

僤鯓⒐⒋嵵緔 提交于 2020-02-04 16:50:29
问题描述: 让我们定义d​n​​为:d​n​​=p​n+1​​−p​n​​,其中p​i​​是第i个素数。显然有d​1​​=1,且对于n>1有d​n​​是偶数。“素数对猜想”认为“存在无穷多对相邻且差为2的素数”。 现给定任意正整数 N (<10​5​​),请计算不超过 N 的满足猜想的素数对的个数。 输入格式: 输入在一行给出正整数 N 。 输出格式: 在一行中输出不超过 N 的满足猜想的素数对的个数。 输入样例: 20 输出样例: 4 问题分析: 这题主要思路就是把不超过N的所有的素数算出来,然后遍历一下,是否满足差为2的相邻素数,满足就在计数中+1。然后输出总数即可。这题核心在于计算素数,素数就是我们小学的时候学的那个质数,即只有1和本身是公因数的数。最笨的办法就是进行遍历相除,当前的数与从2开始一直遍历到比自己小1的那个数进行求余,当出现余数为0时,则不为素数,否则为素数。用这个方式进行求解,在问题提交时,会出现超时的问题。所以,为了提高查找素数的效率,我们只需比较到当前数的开根号即可。因为一个数的公因数都是成对出现的,开根号的情况下,只需要判断少量的参数,这样就可以提升计算效率了。 代码: #pragma warning(disable:4996) #include <stdio.h> #include <math.h> using namespace std; int

PTA1013 数素数

旧街凉风 提交于 2020-02-04 12:09:31
令 P​i​​ 表示第 i 个素数。现任给两个正整数 M≤N≤10​4​​,请输出 P​M​​ 到 P​N​​ 的所有素数。 输入格式: 输入在一行中给出 M 和 N,其间以空格分隔。 输出格式: 输出从 P​M​​ 到 P​N​​ 的所有素数,每 10 个数字占 1 行,其间以空格分隔,但行末不得有多余空格。 输入样例: 5 27 输出样例: 11 13 17 19 23 29 31 37 41 43 47 53 59 61 67 71 73 79 83 89 97 101 103 素数打一下表快速判断;注意输出格式,最后一行不要打两次回车 #include<stdio.h> using namespace std; int p[1000005]; int sushu[100005]; void solve() { int cnt=1; p[1]=1;//bushi sushu for(int i=2;i<1000005;i++) { if(!p[i])//sushu { sushu[cnt++]=i; for(int j=i*2;j<=1000005;j+=i) p[j]=1; } } } int main() { solve(); int n,m; int ans=0; scanf("%d %d",&n,&m); if(m>=n) { for(int i=n;i<=m;i++