Timus Online Judge 哥德巴赫猜想

http://acm.timus.ru/problem.aspx?space=18&num=10

J. Something Easier

Time limit: 1.0 second
Memory limit: 64 MB
“How do physicists define prime numbers? Very easily: prime numbers are the number 2 and all the odd numbers greater than 2. They may show that this definition corresponds to the mathematical one: 3 is prime, 5 is prime, 7 is prime… 9? 9 is certainly not prime. Then: 11 is prime, 13 is prime. So 9 is the experiment mistake.”
From mathematical analysis course
Once physicist and mathematician argued how many prime numbers one needed for the purpose that their sum was equal to  N. One said that it wasn’t known and the other that 3 was always enough. The question is how many.

Input

The first line contains  T, an amount of tests. Then  T lines with integer  N follow (0 ≤  T ≤ 20; 2 ≤  N ≤ 10 9).

Output

For each test in a separate line you should output prime numbers so that their sum equals to  N. An amount of such prime numbers is to be minimal possible.

Sample

input output
7
2
27
85
192
14983
3
7
2
23 2 2
2 83
11 181
14983
3
7
要做题先明白什么是哥德巴赫猜想
解题思路我写在代码里了:
#include <iostream>
using namespace std;

bool nprime(int k)//判断是否是素数
{
    for(int i=2; i*i<=k; ++i)
    {
        if(k%i==0) return 1;
    }
    return 0;
}
int main()
{
    int t,a;
    cin>>t;
    while(t--)
    {
        cin>>a;
        if(!nprime(a)) cout<<a<<endl;
        else if(a%2==0)//如果是偶数则一定可以表示为两个素数的和
        {
            int k=a-3;
            while(nprime(k) || nprime(a-k)) k-=2;
            cout<<k<<" "<<a-k<<endl;
        }
        else//如果是奇数
        {
            int k=a-2;//已经排除它本身不是素数了,则下一个奇数有可能是
            if(!nprime(k))
            {
                cout<<k<<' '<<2<<endl;
                continue;
            }
            k-=2;//如果不是
            while(nprime(k)) k-=2;//直到是
            cout<<k<<" ";
            a=a-k;//此时转化成a-k这个数的素数表示了。由哥德巴赫猜想可得现在这个数一定可以由两个素数的和表示
            if(a==4)//因为素数中2 是一个唯一的偶数,在这里要单独考虑。不能和下一步并在一起,因为下一步考虑的全是奇数的素数
            {
                cout<<2<<' '<<2<<endl;
                continue;
            }
            k=a-3;//一不是素数,二已排除,从三开始
            while(nprime(k) || nprime(a-k)) k-=2;//循环到能成功表示
            cout<<k<<" "<<a-k<<endl;
        }
    }
    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值