素数判断的两种常用办法

1.枚举法

当n比较小时,使用暴力枚举法是可行的,即如果要判断n是否是素数,则令i=2,判断n是否能整除i,直到<=根号n(在此,如果 d 是 n 的约数,那 n/d 也是 n 的约数,则由n=d*n/d 可知 min(d,n/d) <=根号n ,所以只要到根号n就可以, 不必到n-1 )
code:

bool is_prime(int n)
{
	for(int i = 2; i*i<=n ; i++)
	{
		if(n%i==0)
			return false;
	}
	return n!=1;  //1是例外
}

2.打表法(埃氏筛法)

当n比较大,那用枚举法就不太合适了。或者,要求n范围内有多少素数,都可以用此方法来实现。
First of all , 2->n 中最小的素数是2,将表中所有的素数都划掉。剩余最小素数是3,再将3所有的倍数都划掉。依此类推,便能枚举n内所有的素数。

这里写图片描述

code:

int prime[max_N];	//函数里的p是最大下标,即为素数个数,  并可表示第i个素数是多少
int is_prime[max_N+1];	//1为素数,0则不是

int sieve(int n)
{
	int p=0;  //初始化素数个数为0
	for(int i=2;i<=n;i++) is_prime[i]=1;  //初始化所有数均为素数
	is_prime[1]=is_prime[0]=0;
	
	for(int i=2;i<=n;i++)
	{
		if( is_prime[i] )
		{
			prime[p++]=i;  //i是素数
			for(int j=i+i;j<=n;j+=i){
				is_prime[j]=0;  //i的倍数都不是素数 ,所以赋0
			}
		}
	}
	return p;  //返回的p是n以内的素数个数
}

**注:**如果区间不是n以内即0->n ,是 [a,b)内的素数个数的话,也可用此方法求,不过,需先求得 [2,根号b )内的素数表,再筛选 [2,根号b ) 中素数的个数时,同时筛选其倍数 在[a,b) 并将其划去 ,最后即可剩下 [a,b)中素数的个数。

:HDU 1215-七夕节

题目链接:http://acm.split.hdu.edu.cn/showproblem.php?pid=1215

题意:求n以内所有n的因子和

code:

#include <cstdio>
#include <cstring>

#define Max 500002  
int a[Max];  
void panter()  
{  
    int i,j;  
    memset(a,0,sizeof(0));  
    for(i=1;i<Max;i++)  //从1开始,因为每个数都有1这个因子 
    {  
        for(j=2*i;j<Max;j+=i)  
        {  
            a[j]+=i;  //依次加上倍数链的因子
        }  
    }  
}  
int main()  
{  
    int T,n;  
    panter();  
    scanf("%d",&T);  
    while(T--)  
    {  
        scanf("%d",&n);  
        printf("%d\n",a[n]);  
    }  
    return 0;  
}  
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值