欧拉筛及模板题

欧拉筛

思想:每个数都只被其最小的素因子筛掉一次

#include <stdio.h>

using namespace std;
int a[10000005];   ///a[i]数组可以用来判断i是否为素数(a[i]==1则i为合数,a[i]==0则i为素数);
int prime[10000005];
void getprime(int n)
{
    int cnt=0;              ///素数个数的计数器
    for(int i=2;i<n;i++)///从2开始,因为2是第一个素数
    {
        if(a[i]==0) prime[cnt++]=i;/// i已经被比他小的所有素数筛过了,所以若a[i]==0,则其为素数
        for(int j=0;j<cnt&&prime[j]*i<=n;j++)///j<cnt,为了保证prime[j]为素数,prime[j]*i<=不多筛也防止越界
        {
            a[prime[j]*i]=1;    ///筛掉prime[j]的i倍,如2的1,2,3...倍,但是3的话就从3,4,5...倍开始筛,
            			        ///因为3的2倍'6'已经被2筛掉了,以此类推
            if(i%prime[j]==0) break;///保证每个数都只被其最小的素因子筛掉一次
        }
    }
}

例题
Goldbach’s Conjecture

For any even number n greater than or equal to 4, there exists at least one pair of prime numbers p1 and p2 such that

n = p1 + p2

This conjecture has not been proved nor refused yet. No one is sure whether this conjecture actually holds. However, one can find such a pair of prime numbers, if any, for a given even number. The problem here is to write a program that reports the number of all the pairs of prime numbers satisfying the condition in the conjecture for a given even number.

A sequence of even numbers is given as input. There can be many such numbers. Corresponding to each number, the program should output the number of pairs mentioned above. Notice that we are interested in the number of essentially different pairs and therefore you should not count (p1, p2) and (p2, p1) separately as two different pairs.

Input
An integer is given in each input line. You may assume that each integer is even, and is greater than or equal to 4 and less than 2^15. The end of the input is indicated by a number 0.

Output
Each output line should contain an integer number. No other characters should appear in the output.

Sample Input
6
10
12
0
Sample Output
1
2
1
题目大意:一个数分解成两个素数有几种分法

#include<iostream>
#include<cstdio>
using namespace std;
typedef long long ll;
int a[1000000];
int prime[100000];
int getprime(int n)
{
    int i;int cnt=0;
    for(i=2;i<=n;i++ )
    {
        if(a[i]==0) prime[cnt++]=i;
        for(int j=0;i*prime[j]<=n&&j<cnt;j++)
        {
            a[prime[j]*i]=1;
            if(i%prime[j]==0) break;
        }
    }
    return cnt;
}
int main()
{
    long  n;
    for(;;)
    {
        cin>>n;int cnt1=0;
        if(n==0) break;
        int cnt=getprime(n);
        for(int i=0;i<cnt&&prime[i]<=n/2;i++)
        {
            long b=n-prime[i];
            for(int j=0;j<cnt;j++)
            if(prime[j]==b){cnt1++;break;}
        }
        cout<<cnt1<<endl;
    }

}

例题2
Primes

Write a program to read in a list of integers and determine whether or not each number is prime. A number, n, is prime if its only divisors are 1 and n. For this problem, the numbers 1 and 2 are not considered primes.
Input
Each input line contains a single integer. The list of integers is terminated with a number<= 0. You may assume that the input contains at most 250 numbers and each number is less than or equal to 16000.
Output
The output should consists of one line for every number, where each line first lists the problem number, followed by a colon and space, followed by “yes” or “no”.
Sample Input
1
2
3
4
5
17
0
Sample Output
1: no
2: no
3: yes
4: no
5: yes
6: yes
题目大意:判断number是否为素数

#include<iostream>
#include<cstdio>
using namespace std;
///根据数组a[i]判断i是否为素数
typedef long long ll;
int a[1000000];
int prime[100000];
void getprime(int n)
{
    int i;
    int cnt=0;
    for(i=2; i<=n; i++ )
    {
        if(a[i]==0)
            prime[cnt++]=i;
        for(int j=0; i*prime[j]<=n&&j<cnt; j++)
        {
            a[prime[j]*i]=1;
            if(i%prime[j]==0)
                break;
        }
    }
}
int main()
{
    int  n;
    getprime(16005);
    prime[0]=-1;
    for(int k=1;; k++)
    {
        scanf("%d",&n);
        if(n<=0) break;///一开始漏了'<'导致T
        if(n==2||n==1) printf("%d: no\n",k);
        else if(a[n]==0)  printf("%d: yes\n",k);
        else if(a[n]==1)  printf("%d: no\n",k);
    }

}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值