URAL 1356 哥德巴赫猜想

题意:给出一个数,把它分解成几个素数相加的形式,要求分解出的素数的数量最小。

这题分情况讨论就可以了,首先需要知道哥德巴赫猜想即一个大于4的偶数可以分解成两个素数和的形式。其次需要知道奇数加奇数等于偶数,奇数减奇数等于偶数。

那么首先判断n是否是素数,如果是直接输出n就可以。

接下来判断如果n是奇数,那么先判断n-2是否是素数,如果是的话那么最小数量的素数和即n-2 与 2,如果不是那么肯定能减一个奇素数数得到一个偶数再分解成两个素数。这个奇素数首选肯定是3,因为3最小适合绝大多数情况。

如果n是偶数,那么直接分解成两个素数即可。 

分解偶数直接枚举素数暴力就可以了。这里数据弱了,n不大于maxn可行,不然还是得一个一个枚举。

#include <iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<map>
#include<set>
using namespace std;
#define maxn 100010
bool isprime[maxn];
int prime[maxn],nprime;
void getprime()
{
    memset(isprime,1,sizeof(prime));
    long long i,j;
    nprime=0;
    for(i=2; i<maxn; i++)
        if(isprime[i])
        {
            prime[nprime++]=i;
            for(j=i*i; j<maxn; j+=i)isprime[j]=0;
        }
}
bool judgeprime(int n)
{
    if(n<maxn)return isprime[n];
    int l=(int)sqrt(n*1.0);
    for(int i=0; prime[i]<=l; i++)
        if(n%prime[i]==0)return 0;
    return 1;
}
void divideeven(int n,int &x,int &y)
{
    for(int i=1; prime[i]<n; i++)
        if(judgeprime(n-prime[i]))
        {
            x=prime[i],y=n-x;
            return;
        }
}
int main()
{
    int t,n,x,y;
    getprime();
    scanf("%d",&t);
    while(t--)
    {
        scanf("%d",&n);
        if(judgeprime(n))
        {
            printf("%d\n",n);
            continue;
        }
        if(n&1)
        {
            if(judgeprime(n-2))printf("2 %d\n",n-2);
            else divideeven(n-3,x,y),printf("3 %d %d\n",x,y);
        }
        else divideeven(n,x,y),printf("%d %d\n",x,y);
    }
    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值