Goldbach

Description:

Goldbach’s conjecture is one of the oldest and best-known unsolved problems in number theory and all of mathematics. It states:

Every even integer greater than 2 can be expressed as the sum of two primes.

The actual verification of the Goldbach conjecture shows that even numbers below at least 1e14 can be expressed as a sum of two prime numbers.

Many times, there are more than one way to represent even numbers as two prime numbers.

For example, 18=5+13=7+11, 64=3+61=5+59=11+53=17+47=23+41, etc.

Now this problem is asking you to divide a postive even integer n (2

Input:

The first line of input is a T means the number of the cases.

Next T lines, each line is a postive even integer n (2

Output:

The output is also T lines, each line is two number we asked for.

T is about 100.

本题答案不唯一,符合要求的答案均正确

样例输入

1
8

样例输出

3 5

题意

给出一个偶数n,让你输出任意一组素数a,b满足a+b=n

思路

首先可以预处理出2e6的素数表,枚举素数表中的素数x并且用米勒罗宾素数判定来判断一下(n-x)是否为素数,如果符合题意,就输出并且跳出循环,当数据很大在素数表中没有符合题意的结果时,就暴力找一下素数,可以从n/2分别往两侧找,用米勒罗宾素数判断来判一下当找到两个数都是素数时就可以了
附AC带码

#include <bits/stdc++.h>

using namespace std;
typedef long long LL;
LL prime[6] = {2, 3, 5, 233, 331};
LL qmul(LL x, LL y, LL mod) { 
    return (x * y - (long long)(x / (long double)mod * y + 1e-3) *mod + mod) % mod;
}
LL qpow(LL a, LL n, LL mod) {
    LL ret = 1;
    while(n) {
        if(n & 1) ret = qmul(ret, a, mod);
        a = qmul(a, a, mod);
        n >>= 1;
    }
    return ret;
}
bool Miller_Rabin(LL p) {
    if(p < 2) return 0;
    if(p != 2 && p % 2 == 0) return 0;
    LL s = p - 1;
    while(! (s & 1)) s >>= 1;
    for(int i = 0; i < 5; ++i) {
        if(p == prime[i]) return 1;
        LL t = s, m = qpow(prime[i], s, p);
        while(t != p - 1 && m != 1 && m != p - 1) {
            m = qmul(m, m, p);
            t <<= 1;
        }
        if(m != p - 1 && !(t & 1)) return 0;
    }
    return 1;
}
const int maxn = 1<<16;
LL primee[maxn], notPrime[maxn], priCnt=0;

void getPrime() {
    for (int i = 2; i < maxn; i++) {
        if (!notPrime[i])
            primee[priCnt++] = i;
        for (int j = 0; j < priCnt && i * primee[j] < maxn; j++) {
            notPrime[i * primee[j]] = 1;
            if (i % primee[j] == 0) break;
        }
    }
}
int main()
{
   int t;
   long long n;
   getPrime();
   printf("%lld\n",priCnt);
   scanf("%d",&t);
   while(t--)
   {
       scanf("%lld",&n);
       int f=0;
       for(long long i=0;i<priCnt;i++)
       {
           if(Miller_Rabin(n-primee[i]))
           {
               f = 1;
               printf("%lld %lld\n",primee[i],n-primee[i]);
               break;
           }
       }
       if(f==0)
       {
           long long p=n/2,i;
           if(p%2==0)
            i = 1;
           else
            i = 0;
           for(i;;i+=2)
           {
               if(Miller_Rabin(p-i),Miller_Rabin(p+i))
               {
                   printf("%lld %lld\n",p-i,p+i);
                   break;
               }
           }
       }
   }
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值