判断素数

素数的判断

时光总嘲笑我的痴心妄想 提交于 2019-11-30 16:33:53
素数: 质数是指在大于1的自然数中,除了1和它本身以外不再有其他因数 的自然数。 例题:判断一个数在[a,b]之间的素数个数,以及素数的综合 C语言 #include <stdio.h> #include <math.h> int main() { int i,j;     //i是控制m,n的范围,j是从2到i的开方寻找 int m,n;     //输入取值范围m,n int sum1,sum2;     //sum1代表素数的个数,sum2代表素数的和 /* * 思想是判断素数;当然判断一个数不是素数要比判断一个数是素数容易,所以设起始素数变量为1 * 如果不是素数就变为0 * 还有一点要注意1不是素数,所以如果起始是1时,我们可以把它变成下一个数,即2 */ scanf("%d %d",&m,&n); if(m==1) m=2; for(i = m;i <= n; i++) { int isPrime = 1; for(j = 2;j <= sqrt(i); j++) { if(i%j==0) { isPrime = 0; break; } } if(isPrime) { sum1++; sum2+=i; } } printf("%d %d",sum1,sum2); } 来源: https://www.cnblogs.com/icesunbo/p/11604409.html

素数回文

可紊 提交于 2019-11-30 16:02:47
#include <iostream> #include <string> #include <cmath> #include <vector> using namespace std; bool isS(int n);//判断素数 bool isP(int n);//判断回文 int main() { vector<int>res; int a, b; cin >> a >> b; for (int i = a; i <= b; i++) { if (isS(i) && isP(i)) res.push_back(i); } int l = res.size(); for (int i = 0; i < l-1; i++) { cout << res[i] << "\n"; } cout << res[l-1]; return 0; } bool isS(int n) { int l = (int)sqrt(n); for (int i = 2; i <= l; i++) { if (n % i == 0) return false; } return true; } bool isP(int n) { //if n == reverseN return true; int reverseN = 0; int tmp = n; while (tmp > 0) { reverseN

CQOJ921B素数和

梦想与她 提交于 2019-11-30 05:49:41
这是用一道搜索(全排列)实现的一个数论题目。今天周六,上了一天信息,没写数学的我瑟瑟发抖。 首先题意为给定n个数,选取k个数进行求和,输出和为素数的方案数。在写判断素数函数时,我们只需要把i枚举到 根下x 即可,这一点可以证明。在写全排列列时,由于我们需要枚举的是和,所以不需要再考虑顺序了,要用到三个变量 (int now,int step,int sum ){表示当前枚举到第几个,当前有几个数,当前的和,生成一种排列后直接判断即可。另lyx tql 1.牢记素数判断优化。 2.想搜索的过程中需要几个变量记录状态。 代码 #include<iostream> #include<cstdio> #include<cstring> #include<string> #include<algorithm> #define maxn 21 using namespace std; int n,k; int a[100]; int ans=0; bool judge(int x){ if(x==1) return true; for(int i=2;i*i<=x;i++){ if(x%i==0) return false; } return true; } void dfs(int now,int step,int sum){//当前枚举到第几个,当前有几个数,当前的和 if(step==k

Miller-Rablin与Pollard-Rho算法(素性测试与质因数分解)

坚强是说给别人听的谎言 提交于 2019-11-30 03:51:40
前置 费马小定理(即若P为质数,则 \(A^P\equiv A \pmod{P}\) )。 欧几里得算法(GCD)。 快速幂,龟速乘。 素性测试 引入 素性测试是OI中一个十分重要的事,在数学毒瘤题中有着举足轻重的地位。 常见的素性测试如下: int check(int N){ for(int i=2;i*i<=N;i++) if(N%i==0)return 0; return 1; } 以上是一个 \(O(\sqrt{N})\) 的算法,虽然不优,但在绝大多数情况下是可以的。 但是,假如 \(N\) 的范围达到了 \(1e18\) ,以上算法很明显就不行了,我们得考虑更优的算法。 引入Miller-Rablin算法。 定理1 定理1:如果 \(P\) 为一个 大于2 的素数,那么方程 \(X^2\equiv1 \pmod{P}\) 的解只有1或者-1。 (是真得水的) 证明如下: 由 \(X^2\equiv1 \pmod{P}\) ,得 \((X^2-1)\equiv0 \pmod{P}\) , 即 \({(X+1)(X-1)}\equiv0 \pmod{P}\) 。 则 \(P | (X+1)\) 或 \(P|(X-1)\) , 即 \((X+1)\equiv0 \pmod{P}\) 或 \((X-1)\equiv0 \pmod{P}\) 。 则 \(X\equiv-1

定义一个判断素数的函数

心不动则不痛 提交于 2019-11-29 13:33:20
#include<stdio.h> //定义一个函数判断素数 void sushu(int s){ int i,j,k=0; for(i=2;i<s;i++) if(s%i==0){ k=1; break; } if(k==1) printf("%d不是素数",s); if(k==0) printf("%d是素数"); return 0; } //验证 int main() { int a; while(1){ printf("\n请输入要判断的数:\n"); scanf("%d",&a); sushu(a); } return 0; } 来源: https://www.cnblogs.com/gougouwang/p/11518591.html

【C++】欧拉素数筛的理解与实现

独自空忆成欢 提交于 2019-11-29 11:58:28
在传统的素数筛法中,我们使用了对于每一个数n,在 1~(√n) 范围内进行取模检查,这样逐一判断的复杂度为n(√n)。 但如果我们需要更快的筛法时怎么办? 于是著名的 欧拉筛 诞生了。它能将复杂度降为 O(n) 级别。 1.关键理解: 欧拉筛的原理是保证在 2~n 范围中的每一个合数都能被 唯一分解成它的最小质因数与除自己外最大的因数相乘的形式 。因此我们枚举2~n中的每一个数作为筛法中的“除自己外的最大因数”,如果它未被标记为合数,就先将它放入素数表内,再将这个最大因数与素数表中已经找到的素数作为最小质因数相乘,将得到的这些数标记为合数。最后输出得到的素数表即可。 但是我们如何保证 每个合数都被唯一分解 ? 解决方法如下: 当此时取出的素数表中的素数(即枚举的最小质因子)整除于当前枚举的合数时,我们就停止循环素数表,开始枚举下一个合数。 证明如下: 设当前枚举的最小质因子prime[i]整除于合数n时,即我们要筛掉合数 n*prime[i] ;如果我们此时不退出,继续枚举下一个素数prime[i+1],对于将要筛掉的合数 n*prime[i+1] 由于插入顺序从小到大,则 prime[i+1]>prime[i] 。由于prime[i]整除于合数n,所以必然合数 n*prime[i+1] 还可以被分解为 $$ (\frac n {prime[i]} prime[i+1])

PAT A1116 Come on! Let's C [素数+STL模拟]

僤鯓⒐⒋嵵緔 提交于 2019-11-29 04:57:32
题目描述 链接 素数判断+map存储 代码 #include<bits/stdc++.h> using namespace std; int n,k; map<string, string> mp; map<string, bool> check; bool is_prime(int n){ if(n < 2) return false; for(int i=2; i<=sqrt(n); i++){ if(n % i == 0) return false; } return true; } int main(){ cin>>n; string s; for(int i=1;i<=n;i++){ cin>>s; if(i==1) mp[s] = "Mystery Award"; else if(is_prime(i)){ mp[s] = "Minion"; }else{ mp[s] = "Chocolate"; } } cin>>k; while(k--){ cin>>s; if(mp.find(s) == mp.end()){ cout<<s<<": Are you kidding?"<<endl; }else if(check[s] == false){ check[s] = true; cout<<s<<": "<<mp[s]<<endl; }else{ cout<<s<<":

BZOJ 1053 反素数 题解

空扰寡人 提交于 2019-11-29 03:21:20
题面 引理1: 1~n中的最大反质数,就是1~n中约数个数最多的数中最小的一个(因为要严格保证g(x)>g(i)); 引理2:1~n中任何数的 不同 因子不会超过10个,因为他们的乘积大于2,000,000,000; 引理3: 1~n中任何数的质因子的指数总和不超过30; 引理4: x的质因子是连续的若干个最小的质数,并且指数单调递减; 对于指数的排列我们只要深搜就可以找到方案,对于不同情况判断是否更新答案; #include <bits/stdc++.h> using namespace std; long long n; long long ans=99999999999999; int a[15]={0,2,3,5,7,11,13,17,19,23,29,31}; inline long long KSM(long long a,long long b) { long long res=1; while(b){ if(b&1) res=res*a; a=a*a; b/=2; } return res; } long long cnt=-1; inline void dfs(int dep,int now,long long sum,long long num) { if(sum>n||sum<0){ return; } if(num>cnt){ ans=sum; cnt

有关素数的基础算法

倖福魔咒の 提交于 2019-11-29 00:56:26
所谓素数,是指恰好有2个约数的整数。因为n的约束都不超过n,所以只要检查2~n-1的所有整数是否整出n就能判定n是不是素数。在此,如果d是n的约数,那么n/d也是n的约数。由n=d×n/d可知min(d,n/d)<= ,所以只要检查2~ 的所有整数就够了。同理可知,整数分解和约数枚举都可以在 时间完成,虽然还有更高效的算法(费马测试, 算法,数域筛法等),不过多数情况下这已经足够了。——挑战程序设计竞赛p117 1.素数测试 给定一个整数n,请判断n是不是素数。(1<=n<=10的9次方) 代码: #include<iostream> #include<vector> #include<map> #include<algorithm> using namespace std; //假设输入都是正数 //素性测试 bool is_prime(int n) { for (int i = 2; i*i <= n; i++) { if (n%i == 0) return false; } return n != 1;//1是例外 } //约数枚举 vector<int> divisor(int n) { vector<int> res; for (int i = 1; i*i <= n; i++) { if (n%i == 0) { res.push_back(i); if (i != n

素数筛选

限于喜欢 提交于 2019-11-28 22:10:25
简单的引入一下欧拉函数 素数筛选知道4种,暴力筛(逐个判断),埃拉特斯特尼筛 ,欧拉线性筛 ,一个大于5的素数一定在6的倍数周围(PS:不知道官方名是什么) 埃拉特斯特尼筛法。时间复杂度为O(n loglog n) //倍数筛除 时间复杂度(o(nloglogn) //一个素数的倍数一定不是素数 int vis[1000] , prime[1000]; void judge() { memset(vis,1,sizeof(vis)); int cnt=0; prime[0] = prime[1] = 0; for(int i=2;i<1000;i++) { if(vis[i]) { prime[cnt++] = i; //cout<<prime[cnt-1]<<endl; for(int j=i*i;j<1000;j+=i) vis[j] = 0; } } } 欧拉线性筛法 时间复杂度(o(n) ) //欧拉线性筛法 时间复杂度(o(n)) const int MAXN=3000001; int prime[MAXN];//保存素数 bool vis[MAXN];//初始化 void Prime(int n) { int cnt=0; memset(vis,1,sizeof(vis)); for(int i=2;i<=n;i++) { if(vis[i]) { prime[cnt+