素数题

涉及素数的目前遇到2种
1.计算有多少个素数。
用线性筛法。如洛谷题目P3912

#include<algorithm>
#include<cstdio>
#include<cmath>
using namespace std;
const int large=1e9;
bool noprime[large];
int main(void)
{int sum=0,i,d;
int maxn;
scanf("%d",&maxn);
sum=maxn-1;
    for(i=2;i<=sqrt(maxn);i++)//这里注意用sqrt,不然依然tle,数学的精华呀
{
    if(noprime[i]==0)
    {//此处体现线性筛法
        for(d=2*i;d<=maxn;d=d+i){if(noprime[d]==0)sum--;noprime[d]=1;}
        }
}
    printf("%d",sum);

    return 0;
}

2.判断是否是素数 (洛谷题目P3383)
也可以用第一种方法,建一个素数表,如以下

#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
using namespace std;
//const int maxn=1e7;
int maxn;
bool prime[10000000];
int main(void)
{int i,d;
 int a,b,c;
    scanf("%d %d",&a,&b);
    maxn=a;
    memset(prime,1,sizeof(prime));
    prime[0]=0;prime[1]=0;
    for(i=2;i<=sqrt(maxn);i++)
    {if(prime[i]==0)continue;
        for(d=i+i;d<=maxn;d=d+i)
            {
                prime[d]=0;
            }
    }

    while(b--)
    {
        scanf("%d",&c);
        if(prime[c])printf("Yes\n");
        else printf("No\n");
    }


}

但是看了其他人的解法,还有更快的,就是遇到一个素数时,再去判断它。当范围比较大时,样例比较少时。

#include<cstdio>
#include<iostream>
#include<cstring>
#include<cmath>
using namespace std;
int m,n;
bool isp(int n)
{
    if(n==1||n==4) return false;
    if(n==2 || n==3) return true;
    if(n%6 != 1 && n%6 != 5) return false;
    int qt=sqrt(n);
    for(int i=5;i<=qt;i+=6)
    {
    	if((n%i)==0 || n%(i+2) == 0) return false;
    }
    return true;
}


int main(void)
{
    scanf("%d%d",&n,&m);
    for(int i=1;i<=m;i++)
    {
        int tmp;
        scanf("%d",&tmp);
        if(isp(tmp)) printf("Yes\n");
        else printf("No\n");
    }
    return 0;
}

始终没有弄明白的——uva10539
以下是ac代码,但是不明白为什么把求almost prime number和求prime number在一个循环内时就会错。

#include<vector>
#include<iostream>
#include<cmath>
#include<algorithm>
#include<vector>
#include<cstring>
using namespace std;
bool vis[1000010];
long long primes[78500];
vector<long long >ans;
int find(long long n,int l,int r)
{int mid=(l+r)/2;
if(n<ans[0])return 0;
if(n>ans[ans.size()-1])return ans.size();
if(ans[mid]==n)return mid;
if(l+1==r) return mid+1;
if(n>ans[mid]) return find(n,mid,r);
else return find(n,l,mid);

}
int main(void)
{
    memset(vis,0,sizeof(vis));
    vis[0]=vis[1]=1;
    int cnt=0;
    long long int v;
    for(int i=2;i<=1000000;i++)
    {if(vis[i])continue;
    primes[++cnt]=i;
        for(int j=i+i;j<=1000000;j+=i)vis[j]=1;
   //  v=i*i;
   //while(v<=1000000000000){ans.push_back(v);v=v*i;}   
   //此处就是不明白,为什么这样就会错,举得和下面多加一个循环作用没有区别呀。

    }


   for(int i=1;i<=cnt;i++)
    {
        long long tep=primes[i]*primes[i];
        while(tep<=1000000000000)
        {
            ans.push_back(tep);
            tep*=primes[i];
        }
    }
    sort(ans.begin(),ans.end());
    int t;
    cin>>t;
    long long L,R;
    while(t--)
    {
        cin>>L>>R;
        int fl=find(L,0,ans.size());
        int fr=find(R+1,0,ans.size());
        cout<<fr-fl<<endl;
    }
    return 0;

}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
孪生素数是指两个相邻的素数,其差为2,例如(3, 5)、(5, 7)、(11, 13)等。下面是一道关于C语言中孪生素数的OJ目: 目描述: 输入一个正整数n,求出n以内的所有孪生素数(若存在)。输出格式为每个孪生素数对占一行,数字之间用一个空格隔开。如果不存在孪生素数,则输出"NO"。 输入格式: 输入一个正整数n(n<=1000000)。 输出格式: 按照格式输出符合条件的孪生素数对。 样例输入: 20 样例输出: 3 5 5 7 11 13 思路分析: 我们可以使用筛法来解决这道目。先用筛法求出质数,然后遍历质数数组,如果当前质数与前一个质数相差为2,则说明是一对孪生素数。 参考代码: ```c #include <stdio.h> #include <stdlib.h> #include <stdbool.h> #define MAX_N 1000000 bool is_prime[MAX_N + 1]; // 标记是否为质数 int prime[MAX_N + 1]; // 存储质数 int prime_cnt = 0; // 记录质数的数量 void sieve(int n) { for (int i = 2; i <= n; i++) { if (!is_prime[i]) { prime[prime_cnt++] = i; } for (int j = 0; j < prime_cnt && i * prime[j] <= n; j++) { is_prime[i * prime[j]] = true; if (i % prime[j] == 0) { break; } } } } int main() { int n; scanf("%d", &n); sieve(n); int prev_prime = -1; // 上一个质数 for (int i = 0; i < prime_cnt; i++) { if (prev_prime != -1 && prime[i] - prev_prime == 2) { printf("%d %d\n", prev_prime, prime[i]); } prev_prime = prime[i]; } if (prev_prime == -1) { printf("NO\n"); } return 0; } ```

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

是Mally呀!

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值