Order (a,b) pairs by result of a*b

前端 未结 4 2016
离开以前
离开以前 2021-01-18 18:59

I would like to find the highest value m = a*b that satisfies some condition C(m), where

1 <= a <= b <= 1,000,000.

In order to do

4条回答
  •  生来不讨喜
    2021-01-18 19:30

    Note: this is a test of the function C(m) where m <= some target. It will not work for OP's general situation, but is a side case.

    First find the highest number that satisfies C, and then find the pair that matches that high number. Finding the initial target number takes almost no time since its a binary search from 1 to 1E12. Finding the pair that matches is a bit harder, but is still not as bad as factoring.

    Code:

    public class TargetPractice {
    
        private static final long MAX = 1000000L;
    
        private long target;
    
        public static void main(String[] args) {
            Random r = new Random();
            for (int i = 0; i < 5; i++) {
                TargetPractice tp = new TargetPractice(r.nextInt((int) MAX), r.nextInt((int) MAX));
                System.out.println("Trying to find " + tp.target);
                System.gc();
                long start = System.currentTimeMillis();
                long foundTarget = tp.findTarget();
                long end = System.currentTimeMillis();
                System.out.println("Found " + foundTarget);
                System.out.println("Elapsed time " + (end - start) + "\n");
            }
        }
    
        public TargetPractice(long a, long b) {
            target = a * b + 1;
        }
    
        private long binSearch() {
            double delta = MAX * MAX / 2;
            double target = delta;
    
            while (delta != 0) {
                if (hit((long) target)) {
                    target = target + delta / 2;
                } else {
                    target = target - delta / 2;
                }
                delta = delta / 2;
            }
    
            long longTarget = (long) target;
            for (int i = 10; i >= -10; i--) {
                if (hit(longTarget + i)) {
                    return longTarget + i;
                }
            }
            return -1;
        }
    
        private long findTarget() {
            long target = binSearch();
            long b = MAX;
            while (target / b * b != target || target / b > MAX) {
                b--;
                if (b == 0 || target / b > MAX) {
                    b = MAX;
                    target--;
                }
            }
            System.out.println("Found the pair " + (target/b) + ", " + b);
            return target;
        }
    
        public boolean hit(long n) { 
            return n <= target;
        }
    }
    

    It prints:

    Trying to find 210990777760
    Found the pair 255976, 824260
    Found 210990777760
    Elapsed time 5

    Trying to find 414698196925
    Found the pair 428076, 968749
    Found 414698196924
    Elapsed time 27

    Trying to find 75280777586
    Found the pair 78673, 956882
    Found 75280777586
    Elapsed time 1

    Trying to find 75327435877
    Found the pair 82236, 915991
    Found 75327435876
    Elapsed time 19

    Trying to find 187413015763
    Found the pair 243306, 770277
    Found 187413015762
    Elapsed time 23

提交回复
热议问题