两道素数筛选题

(北理工18年复试题)输入m、n(6<=m<=n<=50),则把[m,n]中的所有偶数表示成两个素数相加的形式。输出这些素数及其出现的次数,输出次序按照素数出现的次数从多到少输出;若出现次数相同,按照素数从大到小输出;若偶数有多种素数相加形式,则把所有的情况都输出,每种情况占一行。(叙述极其复杂,尽量表达了)

       输入:6  7      输出:3 2

       输入:14 15   输出: 7 2

                                      11 1 3 1

       输入:8 10     输出: 5 3 3 1

                                      3 2 5 1 7 1

 

#include <cstdio>
#include <iostream>
#include <vector>
#include<math.h>
#include <algorithm>
using namespace std;
struct number{
    int p;  //素数
    int n;  //该素数的个数
};
int m,n;
int p[50];//1-50中的素数
vector<number>vi;
bool cmp(number a,number b)
{
    if(a.n!=b.n)
        return a.n>b.n;
    return a.p>b.p;
}
//判断素数
bool prime(int a)
{
    if(a<=1)return false;
    else if(a==2)return true;
    else
    {
        for(int i=2;i<=sqrt(a);i++)
            if(a%i==0)return false;
         return true;
    }
}
//把50以内的素数存到p数组中
void init()
{
    int k=0;
    for(int i=2;i<=50;i++)
        if(prime(i))p[k++]=i;
}

void GetResult(int x) //当前的偶数为x
{
    if(x>n)//最后一个偶数已经遍历完毕,此时输出所有素数及个数
    {
        sort(vi.begin(),vi.end(),cmp);
        for(int k=0;k<vi.size();k++)
        {
            if(vi[k].n!=0)
            printf("素数:%d  个数:%d   ", vi[k].p, vi[k].n);
        }
        printf("\n");
        return;
    } 
    //p数组:2 3 5 7 11 13 17 19 23 29 31 37 41 43 47
    else
    {
        for(int i=0;p[i]*2<=x;i++)
        {
            int s1=p[i],f1=0;//s1是比较小的质数
            int s2=x-p[i],f2=0;
            number a;
            if(prime(s2))
            {
                for(int k=0;k<vi.size();k++)
                {
                    if(vi[k].p==s1)
                    {
                        f1=1;
                        vi[k].n++;
                    }
                    if(vi[k].p==s2)
                    {
                        f2=1;
                        vi[k].n++;
                    }
                }
                if(f1==0)
                {
                    s1==s2?a.n=2:a.n=1;
                    a.p=s1;
                    vi.push_back(a);
                }
                if(f2==0 && s1!=s2)
                {
                    a.n=1;
                    a.p=s2;
                    vi.push_back(a);
                }
                //继续遍历下一位
                GetResult(x+2);
                //回退
                for(int k=0;k<vi.size();k++)
                {
                    if(vi[k].p==s1)
                       vi[k].n--;
                    if(vi[k].p==s2)
                       vi[k].n--;
                }
            }
        }
    }
}
int main()
{
    //50以内素数的个数共15个:2 3 5 7 11 13 17 19 23 29 31 37 41 43 47
    init();
    scanf("%d%d",&m,&n);
    if(m%2==1)    m++;
    GetResult(m);//深搜函数,入口是最小的偶数
    return 0;
}

与本题处理方法类似的还有牛客网上这道题:质因数个数

题目描述

求正整数N(N>1)的质因数的个数。 相同的质因数需要重复计算。如120=2*2*2*3*5,共有5个质因数。

输入描述:

可能有多组测试数据,每组测试数据的输入是一个正整数N,(1<N<10^9)。

输出描述:

对于每组数据,输出N的质因数的个数。

示例1

输入

120

输出

5
#include<iostream>
#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<math.h>
using namespace std;
bool judge(int a)
{
    if(a==0||a==1)return false;
    else if(a==2) return true;
    else
        for(int i=2;i<=sqrt(a);i++)
            if(a%i==0)return false;
        return true;
}
int main()
{
    int n;
    int zys[10005];
    memset(zys,0,sizeof(zys));
    for(int i=0;i<10000;i++)
        if(judge(i))zys[i]=1;
    scanf("%d",&n);
    int ans=0;
    while(judge(n)==false&&n!=1)
    {
         for(int i=2;i<10000;i++)
        {
            if((zys[i]==1)&&(n%i==0))
            {
                n/=i;
                ans++;
                i--;
            }
        }
    }
    if(judge(n)==true)ans++;
    printf("%d\n",ans);
    return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值