2018 ACM-ICPC B. Goldbach(Java玄学)

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 ,into two prime numbers.

就是给你一个奇数,让你把它拆成俩数,要求都是素数。

看起来很简单,唯一的点就是,这个输入真尼玛大(2的63次方,大概是9e18多一点)……….

要是使用一般的O(根号n)素数判断法,怕是要跑到明年….

一开始队友观察了素数表,发现素数的分布很均匀,不会出现有一大段自然数中不含素数的情况(说明暴力拆是可行的),并且这些素数都以1、7、9、3结尾,就有了第一个“优化”判一下这个数是不是这种结尾再判是不是素数…..

呃,后来想想其实这个优化根本没卵用啊,我们直接找奇数就行了。主要是…..我们根本对1Y没报希望,只是交了试试,居然就直接过了….过了….

后来发现是java自带的米勒罗宾素数判断带来的奇功,这完全是java的胜利。

ac代码:

public class Main {
    public static void main(String[] args) {
        InputReader reader = new InputReader();
        PrintWriter out = new PrintWriter(System.out);
        int t = reader.nextInt();
        while (t-- > 0) {
            long n = reader.nextLong();
            long half = n / 2;
            int get = (int) (half % 10);
            // if (isPrime(n - 5)) {
            // if (Miller_Rabin(n - 5)) {
            if (BigInteger.valueOf(n - 5).isProbablePrime(5)) {
                out.println(5 + " " + (n - 5));
                continue;
            }
            while (half > 0) {
                // System.out.println(half);
                if (get == 1 || get == 7 || get == 9 || get == 3) {
                    // if (isPrime(get)) {
                    // if (Miller_Rabin(half)) {
                    if (BigInteger.valueOf(half).isProbablePrime(5)) {
                        long half2 = n - half;
                        long get2 = half2 % 10;
                        if (get2 == 1 || get2 == 7 || get2 == 9 || get2 == 3) {
                            // if (isPrime(half2)) {
                            // if (Miller_Rabin(half2)) {
                            if (BigInteger.valueOf(half2).isProbablePrime(5)) {
                                out.println(half + " " + half2);
                                break;
                            }
                        }
                    }
                }
                half--;
                get = (int) (half % 10);
            }
        }
        out.close();
    }
}

然后是结束后补题打的代码:

public class Main {
    public static void main(String[] args) {
        InputReader reader = new InputReader();
        PrintWriter out = new PrintWriter(System.out);
        int t = reader.nextInt();
        long n = 0;
        long half = 0;
        while (t-- > 0) {
            n = reader.nextLong();
            half = n / 2;
            if (half % 2 == 0) {
                half -= 1;
            }
            for (; half < n; half += 2) {
                if (BigInteger.valueOf(half).isProbablePrime(5)) {
                    break;
                }
            }
            while (half < n) {
                if (BigInteger.valueOf(n - half).isProbablePrime(5)) {
                    out.println((n - half) + " " + half);
                    break;
                }
                half = BigInteger.valueOf(half).nextProbablePrime().longValue();
            }
        }
        out.close();
    }
}

简洁了很多,但是并没有一开始的快,应该是数据问题了

猜你喜欢

转载自blog.csdn.net/cymbals/article/details/80055928
今日推荐