判断素数

poj3641(学习了)

夙愿已清 提交于 2020-01-14 06:05:46
素数的测试: 费尔马小定理:如果p是一个素数,且0<a<p,则a^(p-1)%p=1. 利用费尔马小定理,对于给定的整数n,可以设计素数判定算法,通过 计算d=a^(n-1)%n来判断n的素性,当d!=1时,n肯定不是素数,当d=1时,n很可能是素数. 二次探测定理:如果n是一个素数,且0<x<p,则方程x^2%p=1的解为:x=1或 x=p-1. 利用二次探测定理,可以再利用费尔马小定理计算a^(n-1)%n的过程 中增加对整数n的二次探测,一旦发现违背二次探测条件,即得出n不是素数的结论. 如果n是素数,则(n-1)必是偶数,因此可令(n-1)=m*(2^q),其中m是正奇数(若n是偶数,则上面的m*(2^q)一定可以分解成一个正奇数乘以2的k次方的形式),q是非负整数,考察下面的测试: 序列: a^m%n; a^(2m)%n; a^(4m)%n; …… ;a^(m*2^q)%n 把上述测试序列叫做Miller测试,关于Miller测试,有下面的定理: 定理:若n是素数,a是小于n的正整数,则n对以a为基的Miller测试,结果为真. Miller测试进行k次,将合数当成素数处理的错误概率最多不会超过4^(-k). 借鉴别人的,虚心学习 #include<iostream>#include<ctime>#include<cstdlib>#include<cmath>

51nod 1186 Miller-Rabin素数测试

醉酒当歌 提交于 2020-01-13 22:22:27
费尔马小定理: 如果p是一个素数,且0<a<p,则a^(p-1)%p=1.利用费尔马小定理,对于给定的整数n,可以设计素数判定算法,         通过计算d=a^(n-1)%n来判断n的素性,当d!=1时,n肯定不是素数,当d=1时,n 很可能是素数. 二次探测定理: 如果 是素数,且 ,则方程 的解为 或 。          利用二次探测定理,可以再利用费尔马小定理计算a^(n-1)%n的过程 中增加对整数n的二次探测,        一旦发现违背二次探测条件,即得出n不是素数的结论. 先贴出long long 范围的代码: 1 /* 2 long long 范围的Miller-Rabin素数测试 3 */ 4 5 #include <iostream> 6 #include <stdio.h> 7 #include <string.h> 8 #include <stdlib.h> 9 #include <time.h> 10 #define ll long long 11 using namespace std; 12 13 //计算a*b%mod 14 ll mod_mul(ll a, ll b, ll n){ 15 ll cnt = 0LL; 16 while(b){ 17 if(b&1LL) cnt = (cnt+a)%n; 18 a=(a+a)%n; 19 b >

Miller-Rabin素数测试学习小计

╄→尐↘猪︶ㄣ 提交于 2020-01-13 07:16:29
1、Miller-Rabin是干啥的?它是用来检测一个数字(一般是很大的数字)是不是素数; 2、Miller-Rabin算法基于的两个定理: (1)费尔马小定理:如果p是一个素数,且0<a<p,则a^(p-1)%p=1.利用费尔马小定理,对于给定的整数n,可以设计素数判定算法,通过 计算d=a^(n-1)%n来判断n的素性,当d!=1时,n肯定不是素数,当d=1时,n 很可能是素数. (2)二次探测定理:如果p是一个素数,且0<x<p,则方程x^2%p=1的解为:x=1或x=p-1. 3、利用二次探测定理,可以再利用费尔马小定理计算a^(n-1)%n的过程中增加对整数n的二次探测,一旦发现违背二次探测条件,即得出n不是素数的结论.具体来说是这样的:如果n是素数,则(n-1)必是偶数,因此可令(n-1)=m*(2^q),其中m是正奇数,q是非负整数,考察下面的测试: a^(2m)%n; a^(4m)%n; …… ;a^(m*2^q)%n 若上面的式子中a^(2^i*m)%n计算出1来,我们就要看看a^(2^(i-1)*m)是不是等于1或者n-1,若既不是1也不是n-1那么我们判断不是素数。 来源: https://www.cnblogs.com/jianglangcaijin/p/3446859.html

Miller-Rabin素数测试学习笔记

 ̄綄美尐妖づ 提交于 2020-01-12 09:41:14
  好几天前看了算导上的Miller-Rabin素数测试算法,今天正好总结一下,写写笔记。   说Miller-Rabin测试以前先说两个比较高效的求a*b% n 和 a b %n 的函数,这里都是用到二进制思想,将b拆分成二进制,然后与a相加(相乘) // a * b % n//例如: b = 1011101那么a * b mod n = (a * 1000000 mod n + a * 10000 mod n + a * 1000 mod n + a * 100 mod n + a * 1 mod n) mod n ll mod_mul(ll a, ll b, ll n) { ll res = 0; while(b) { if(b&1) res = (res + a) % n; a = (a + a) % n; b >>= 1; } return res;} //a^b % n//同理ll mod_exp(ll a, ll b, ll n) { ll res = 1; while(b) { if(b&1) res = mod_mul(res, a, n); a = mod_mul(a, a, n); b >>= 1; } return res;} 下面开始说Miller-Rabin测试:    费马小定理 :对于素数p和任意整数a,有a p ≡ a(mod p)(同余)。反过来

PAT乙级1007

邮差的信 提交于 2020-01-11 18:33:49
1007 素数对猜想 (20分) 题目地址: https://pintia.cn/problem-sets/994805260223102976/problems/994805317546655744 输入格式: 输入在一行给出正整数 N 。 输出格式: 在一行中输出不超过 N 的满足猜想的素数对的个数。 输入样例 20 输出样例 4 我的理解 找到所有的从1到N之间的素数,素数相减差值为2时,素数对个数加1。 注意1, 2,都是素数的特殊性。 判断素数时,大于2的偶数都不是素数,可以跳过。 判断大于2的数n是不是素数时,只需判断能不能被3到根号n整除即可,数学的知识,目前我也不知道为什么。 代码段 #include<iostream> #include<math.h> using namespace std; int main() { int number = 0; cin >> number; int prime[number]; int index = 0; if (number < 3) { cout << 0 << endl; } else { // 外层遍历,从1到需要判断的数 prime[index++] = 1; prime[index++] = 2; for (int i = 3; i <= number; i += 2) { // 如果是除了2 之外的偶数

判断素数

最后都变了- 提交于 2020-01-09 02:52:13
1.对于判断一个数n是否为素数,最朴素的方法是按素数的定义,试除以从2开始到m-1的整数,如果无一例外地不能整除,则该数一定是素数。 质数(prime number)又称素数,有无限个。 质数又称素数。一个大于1的自然数,除了1和它自身外,不能被其他自然数整除的数叫做质数;否则称为合数。 素数定义 #include<iostream> using namespace std; int n; int main(){ cin>>n; for( int i=2 ; i<=n ; ++i ){ if( n%i==0 ){ cout<<n<<" isn't a prime "<<endl; return 0; } } cout<<n<<" is a prime "<<endl; return 0; } 2.想一想,若2都不能除尽,还要试4, 6, 8, …吗?若3都不能除尽,还要试9, 15, 21, …吗?一个数,如果有因子的话,那么在它的平方根数以内就应该有,否则就没有因子。所以必定有一个因子不大于m的平方根。故判断m是否为素数,只要试除到m的平方根就可以了,不必一直到m-1。 #include<iostream> #include<cmath> using namespace std; int n; int main(){ cin>>n; for( int i=2 ; i<=sqrt

筛选法求素数

ε祈祈猫儿з 提交于 2020-01-08 23:34:55
  求素数的程序是笔试或面试中会经常被问到的题目,大四找工作面试时,就被一个面试官问到了,虽然写出的代码能够完成题目要求,但是面试官并不满意,原因当然在程序的效率上,面试官反复问及如何对原有程序进行优化,想了半天除了将偶数剔除,再无其他想法,这也导致最后投递的岗位从研发变成offer中的测试。   素数的定义为,一个大于1的自然数,除了1和它本身外,不能被其他自然数整除(除0以外)的数称之为素数(质数);否则称为合数。对计算机专业的毕业生来说,这道题并不陌生,比如求N以内的所有素数,通常的解法为: 1 void PrimeNum(int n) 2 { 3 bool *bIsPrime = new bool[n+1]; //申请n+1来表示从1到n 4 for(int i=0; i!=n+1; i++) 5 if(i%2 == 0) 6 bIsPrime[i] = false; 7 else 8 bIsPrime[i] = true; 9 10 bIsPrime[2] = true; //2为素数 11 12 int j, k, nSqrt; 13 for(j=3; j<=n; j+=2) 14 { 15 nSqrt = sqrt(j); 16 for(k=3; k<=nSqrt; k++) 17 if(j%k == 0) 18 { 19 bIsPrime[j] = false;

程序设计第五题 素数判定

非 Y 不嫁゛ 提交于 2020-01-07 11:41:27
Problem Description 对于表达式n^2+n+41,当n在(x,y)范围内取整数值时(包括x,y)(-39<=x<y<=50),判定该表达式的值是否都为素数。 Input 输入数据有多组,每组占一行,由两个整数x,y组成,当x=0,y=0时,表示输入结束,该行不做处理。 Output 对于每个给定范围内的取值,如果表达式的值都为素数,则输出"OK",否则请输出“Sorry”,每组输出占一行。 第五题:素数判定。多次运用条件结构和循环结构判断,注意每次都要进行初始化return 0。 #include<iostream> int su(int n){ int i; if(n<2) return 0; for(i=2;i*i<=n;i++) { if(n%i==0) return 0; } return 1;} int main(){ int x, y, i, s; while(scanf("%d%d",&x,&y)) { if(x==0&&y==0) break; for(i=x;i<=y;i++) { s=i*i+i+41; if(!su(s)) { printf("Sorry\n"); break; } } if(i==y+1) printf("OK\n"); } return 0;} 来源: CSDN 作者: Ashleymi 链接: https://blog

欧拉线性筛更新(猜想)

北城以北 提交于 2020-01-07 08:30:21
猜想 猜想 使用欧拉线性筛解决素数打表预处理,然后再利用巧妙的一部求和 代码实现如下 # include <bits/stdc++.h> using namespace std ; const int N = 16777216 ; //根据题目范围,定义素数筛范围 int prime [ N + 1 ] , n , n1 , c ; //prime素组用于欧拉线性筛处理 bool isprime [ N + 1 ] ; //布尔类型存取是否为素数 int main ( ) { memset ( isprime , true , sizeof ( isprime ) ) ; //先默认所有数为素数 for ( int i = 2 ; i < N ; i ++ ) { if ( isprime [ i ] ) prime [ c ++ ] = i ; //存素数 for ( int j = 0 ; j < c && prime [ j ] * i <= N ; j ++ ) { isprime [ prime [ j ] * i ] = false ; if ( i % prime [ j ] == 0 ) break ; //详见上一篇关于欧拉的博客 } } while ( scanf ( "%d" , & n ) != EOF ) { n1 = 0 ; for ( int i =

打印出100以内的素数

纵饮孤独 提交于 2020-01-06 01:24:38
/** * @author Administrator * 打印出100以内的素数 */ public class PrimeNumber { final static int N = 100; static boolean judgePrime(int n)//判断一个数是否为素数 { for(int i=2 ; i<n ; i++) { if(n%i==0) return false; else continue; } return true ; } public static void main(String[] args) { System.out.println("\n1~100以内的素数有:"); for (int i=1 ; i<N/2 ; i++) { if(judgePrime(i)) System.out.print(i+" "); } System.out.println(); for (int i=N/2 ; i<N ; i++) { if(judgePrime(i)) System.out.print(i+" "); } } } 运行结果: 1~100以内的素数有: 1 2 3 5 7 11 13 17 19 23 29 31 37 41 43 47 53 59 61 67 71 73 79 83 89 97 来源: https://www.cnblogs