筛选法
求出n以内的素数,最快的应该是筛选法。
筛选法的思路是:
要求10000以内的素数,把1-10000都列出来,1不是素数,划掉;2是素数,所有2的倍数都不是素数,划掉;取出下一个幸存的数,划掉它的所有倍数;直到所有素数找完为止。
这种做法的空间复杂度是O(n),时间复杂度O(n/logn)。
const int Max = 1000005;
bool prime[Max]={0};//0表示素数,1为非素数
//筛选n以内的素数
void getPrime(int n)
{
int i,j;
int t;
for(i = 2; i <= n; i++)
{
if(!prime[i])
{
for(j = 2; (t=j*i) <= n; j++)
prime[t] = 1;
}
}
}
分解素因子
唯一质因子分解定理:任意一个合数a仅能以一种方式,写成如下的乘积形式:
a = p1^e1*p2^e2*...*pr^er
其中pi为素数,p1<p2<...<pr,且ei为正整数。例如数6000=2^4*3*5^3。
素因子的分解技巧:首先a的某两个素因子不可能同时大于sqrt(a),这样,先用筛选法求出sqrt(a)以内的所有素数,然后用a依次去mod这些素数,若能整除,则找到素因子,将素因子去掉,再继续找。最后若a>1,则a也是它的素因子。
const int Max = 100005;
int isPrime[Max]={0};
int prime[Max/5],num=0;
int factors[100],s=0;
void getPrime(int n)
{
int i,j;
int t;
for(i = 2; i <= n; i++)
{
if(!isPrime[i])
{
prime[num++] = i;
for(j = 2; (t=i*j) <= n; j++)
isPrime[t] = 1;
}
}
}
void decompose(int n, int* factors)
{
int te = (int)sqrt(n*1.0);
for(int i = 0; i<num&&prime[i]<=te; i++)
{
if(n%prime[i]==0)
{
factors[s++] = prime[i];
while(n%prime[i]==0)
n = n/prime[i];
}
}
if(n > 1)
factors[s++] = n;
}
例
POJ2262
题意:给出任意一个正整数n(n<=10^6),根据哥德巴赫猜想:任意一个不小于6的整数,都可以表示为两个奇素数之和。问虽任意整数是否满足这个猜想。
解:筛选法将n以内的所有素数都求出来,若a是素数,判断n-a是否为素数,若找到一组不满足,则答案为否定。
POJ1142
题意:给一个数n(n<=10^7),求最小的m>n,使得m的素因子每一位上的数的和 == m的每一位上的数的和。
解:显然这题就是要分解素因子。先求10^4以内的素数,再用素因子分解,然后判断。
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
using namespace std;
const int Max = 10005;
bool isPrime[Max]={0};
int prime[Max/4],num=0;
void getPrime(int n)
{
int t;
for(int i = 2; i <= n; i++)
{
if(isPrime[i]==0)
{
prime[num++] = i;
for(int j = 2; (t=j*i) <= n; j++)
isPrime[t] = 1;
}
}
}
int getSum(int n)
{
int ret = 0;
while(n)
{
ret += n%10;
n /= 10;
}
return ret;
}
bool isSmith(int n)
{
int t = (int)sqrt(n*1.0);
int r1 = getSum(n);
int r2 = 0;
int N = n;
for(int i = 0; i<num&&prime[i]<=t; i++)
{
if(n%prime[i]==0)
{
int tmpt = getSum(prime[i]);
while(n%prime[i]==0)
{
n = n/prime[i];
r2 += tmpt;
}
}
}
if(n > 1)
r2 += getSum(n);
if(n==N)
return false;
return r1==r2;
}
int main()
{
int i;
int n;
getPrime(Max-1);
while(true)
{
scanf("%d",&n);
if(!n)
break;
for(i = n+1; ;i++)
{
if(isSmith(i))
break;
}
printf("%d\n",i);
}
return 0;
}
分享到:
相关推荐
ACM数论——ppt(天津大学)ACM数论——ppt(天津大学)
初等数论中整数的标准分解式程序初等数论中整数的标准分解式程序初等数论中整数的标准分解式程序初等数论中整数的标准分解式程序
初等数论中判断一个整数是否为质数程序初等数论中判断一个整数是否为质数程序初等数论中判断一个整数是否为质数程序初等数论中判断一个整数是否为质数程序初等数论中判断一个整数是否为质数程序
Matlab在数论研究中的应用——用Matlab验证哥德巴赫猜想与孪生素数猜想
可用于数论计算的无符号大整数类
素数判定与大数分解问题在数论中占有重要地位,远古时代人们就十分重视它的研究,近年来,由于计算机科学的发展,使这一古老的问题焕发了青春,形成了数论中的新分支——计算数论,《<数学中的小问题大定理>丛书(第...
2.一个整数N的约数个数的上界为. 3.1-N 每个数的约数个数综合大约为N * log N 个。 4.1-1e9中的数,约数个数最多的数仅有1536个约数 倍数法求1-N中所有数的约数集合:NlogN void gao() { vectorfactor[M]; for...
分别实现RSA加密算法和RSA签名算法,对RSA的设计有较好的认识,体会RSA的安全性基于数论难题——大整数因子分解问题.
本书论述了算法数论的基本内容,其中包括:连分数、代数数域、椭圆曲线、素性检验、大整数因子分解算法、椭圆曲线上的离散对数、超椭圆曲线。本书的特点是内容涉及面广,在有限的篇幅内,包含了必要的预备知识和数学...
算法-数论- 整数分解.rar
Matlab在数论研究中的应用——用Matlab验证哥德巴赫猜想与孪生素数猜想.pdf
西电的数论算法讲义,研究生课程,计算机学院课程
设p(n)表示整数n>1的最小素因子.本文得到了∑f(n),p(n)uo的渐近式,此处f(n)是一类数论函数。
一-BASIC 3 IO挂 3 快速乘法 3 快速幂 3 进制转换(包括负进制)概念 3 一个数二进制1的个数 3 二-整除问题 3 整除具有的性质 3 ...高斯整数环与高斯素数 10 n!中素数y的个数 10 筛1~n的因子个数O(n) 10
数论及应用里面的试题哦,关于波拉德p-1因子分解法的。
初等数论中判断一个整数m是否存在原根程序初等数论中判断一个整数m是否存在原根程序初等数论中判断一个整数m是否存在原根程序初等数论中判断一个整数m是否存在原根程序初等数论中判断一个整数m是否存在原根程序
本书论述了算法数论的基本内容,其中包括:连分数、代数数域、椭圆曲线、素性检验、大整数因子分解算法、椭圆曲线上的离散对数、超椭圆曲线。本书的特点是内容涉及面广,在有限的篇幅内,包含了必要的预备知识和数学...
初等数论中输出n以内的质数初等数论中输出n以内的质数初等数论中输出n以内的质数初等数论中输出n以内的质数
初等数论 n!的分解式 c语言初等数论 n!的分解式 c语言初等数论 n!的分解式 c语言