1.素数(质数)筛法
问题1:给定一个数n,要求判断其是否为素数(0,1,负数都是非素数)
#include<stdio.h>
#include<math.h>
bool judge(int x){
if(x<1) return false;
int bound = (int)sqrt(x) + 1; //计算枚举上界,多枚举一个也不能少枚举一个数**
for(int i = 2;i<bound;i++){
if(x%i == 0) return false;
}
return true;
}
int main(){
int x;
while(scanf("%d",&x)!= EOF){
puts(judge(x) ? "yes" : "no");
}
return 0;
}
注意:在上例中,sqrt()和strlen()一样是比较耗时的函数之一,先将sqrt(n)+1赋值给bound,再进行循环可减少比较次数。
问题2:给定一个整数n(2<=n<=10000),要求输出所有从1到这个整数之间(不包括1和这个整数)个位为1的素数,如果没有则输出-1(素数之间用空格隔开,最后一个素数没有空格)
#include<stdio.h>
int prime[10000]; //保存筛得的素数
int primeSize; //保存素数的个数
bool mark[10001]; //mark[x]为true才表示该数x被标记为非素数
void init(){
for(int i=1;i <= 1000;i++){ //初试所有数字均未被标记
mark[i] = false;
}
primeSize = 0;
for(int i = 2;i <= 10000;i++){
if(mark[i] == true) continue;
else prime[primeSize++] = i; //若未被标记,则得到一个新的素数
for(int j = i*i;j<=10000;j+=i){ //直接从i*i开始算起,而不是2*i,可避免重复操作
mark[j] = true;
}
}
}
int main(){
init();
int n;
while(scanf("%d",&n)!=EOF){
bool isOutput = false;
for(int i = 0;i<primeSize;i++){
if(prime[i]<n && prime[i] % 10 ==1){ //测试得到的素数是否符合条件
if(isOutput == false){ //如果为第一个,则该数之前不用添加空格
isOutput = true;
printf("%d",primep[i]);
}
else printf(" %d",prime[i]); //否则在输出这个数字前输出空格
}
}
if(isOutput == false){ //如果不存在符合条件的数字
printf("-1\n");
}
else printf("\n");
}
return 0;
}
2.分解素因数(质因数)
问题3:求正整数N(1<N<10^9)的质因数个数,相同的质因数需要重复计算。如120=2 *2 *2 *3 *5,共有5个质因数
#include<stdio.h>
int prime[100001]; //保存筛得的素数
int primeSize; //保存素数的个数
bool mark[100001]; //mark[x]为true才表示该数x被标记为非素数
void init(){
for(int i=1;i <= 1000;i++){ //初试所有数字均未被标记
mark[i] = false;
}
primeSize = 0;
for(int i = 2;i <= 100000;i++){
if(mark[i] == true) continue;
else prime[primeSize++] = i; //若未被标记,则得到一个新的素数
for(int j = i*i;j<=100000;j+=i){ //直接从i*i开始算起,而不是2*i,可避免重复操作
mark[j] = true;
}
}
}
int main(){
init();
int n;
while(scanf("%d",&n)!=EOF){
int ansPrime[30]; //按顺序保存被分解出来的素因数
int ansSize=0; //分解出来素因数个数
int ansNum[30]; //保存被分解出的素因数对应的幂指数
for(int i = 0;i<primeSize;i++){
if(n%prime[i] == 0){
ansPrime[ansSize] = prime[i]; //该数为素因数
ansNume[ansSize] = 0; //初始化幂指数为0
while(n%prime[i] == 0){ //分解出幂指数
ansNum[ansSize]++; //统计幂指数
n/=prime[i];
}
ansSize++;
if(n==1) break;
}
}
if(n!=1){//若测试完仍未被分解至1,则剩余的因数一定是n个大于100000的素因数
ansPrime[ansSize] = n;//记录该大素因数
ansNum[ansSize++] = 1;//其幂指数只能为1
}
int ans = 0;
for(int i = 0;i<ansSize;i++){
ans+=ansNum[i];
}
printf("%d\n",ans);
}
return 0;
}