计算连续的奇数变化

时间:2015-10-14 15:23:45

标签: java algorithm

我目前正在尝试查找目标数字可以表示为两个或更多连续奇数整数之和的次数。我的代码在这里找到了最长的连续赔率序列:

public class consecutiveOdd {

static int target = 1000000;

public static void main(String[] args){

    int longestVariation = -1;

    int totalVariations = 0;

    for (int k = 1;; k++) {
        int i = target / k - k + 1;
        if (i <= 0) {
            break;
        }
        // Check if calculated i, can be the start of 'odd' sequence.
        if (target % k == 0 && i % 2 == 1) {
            longestVariation = k;
            totalVariations += 1;
        }
    }

    System.out.println(longestVariation); 
    System.out.println(totalVariations);

}

}

虽然我不确定它是否确定了正确数量的变化。我有什么东西可以忽略吗?

最佳, 奥特曼

3 个答案:

答案 0 :(得分:0)

为了确保您的代码正常,您可以实现不同的解决方案,您知道它会产生正确的答案并将其与您的有效方法进行比较。你可以这样做:

public class ConsecutiveOdd {

    static String fast(int target) {

        int longestVariation = -1;

        int totalVariations = 0;

        for (int k = 1;; k++) {
            int i = target / k - k + 1;
            if (i <= 0) {
                break;
            }

            if (target % k == 0 && i % 2 == 1) {
                longestVariation = k;
                totalVariations += 1;
            }
        }

        return Integer.toString(longestVariation) + " " + Integer.toString(totalVariations);
    }

    static String slow(int target) {
        int longest_length  = -1;
        int total = 0;
        for (int start = 1; start <= target; start += 2) {
            int sum = 0;
            int t = start;
            int seq_length = 0;
            while (sum < target) {
                sum += t;
                seq_length++;
                t += 2;
            }
            if (sum == target) {
//                System.out.println(start);
//                System.out.println(seq_length);
                if (seq_length > longest_length)
                    longest_length = seq_length;
                total++;
            }
        }
        return Integer.toString(longest_length) + " " + Integer.toString(total);
    }


    static void test(int n) {
        int correct = 0;
        for (int i = 1; i <= n; ++i) {
            if (!slow(i).equals(fast(i))) {
                System.out.printf("Testcase %d: FAIL\n", i);
            } else {
                System.out.printf("Testcase %d: OK\n", i);
                correct++;
            }
        }
        System.out.printf("%d/%d\n", correct, n);
    }

    public static void main(String[] args)
    {
        test(100);
    }
}

答案 1 :(得分:0)

不是真的答案,但它让我想起皮亚杰的保护测试:

7^2 -  (6^2 + 6^2-5^2 + 5^2-4^2 + 4^2-3^2 + 3^2)  - 2^2
☯☯☯☯☯☯☯
☯☯☯☯☯☯☯
☯☯☯☯☯☯☯
☯☯☯☯☯☯☯
☯☯☯☯☯☯☯
☯☯☯☯☯
☯☯☯☯☯


9^2 -  (8^2 + 8^2-7^2 + 7^2)  - 6^2
☯☯☯☯☯☯☯☯☯
☯☯☯☯☯☯☯☯☯
☯☯☯☯☯☯☯☯☯
☯☯☯
☯☯☯
☯☯☯
☯☯☯
☯☯☯
☯☯☯

哪张图有更多弹珠?

1

顺便说一句,任何完美正方形的最长连续奇数分区始终以(x² - 0²)开头,在我们的绘图方法中,它可以被认为是 4 = 1 + 3 9 = 1 + 3 + 5 16 = 1 + 3 + 5 + 7 ...etc.

{{1}}

答案 2 :(得分:0)

简短的回答是肯定的,您的公式将产生正确数量的变化。奇数自然的所有连续序列s的格式为j * k + 2 * p,其中p是金字塔数1 + 2 + 3...+ (k - 1),表示2&#39;我们需要添加到j以生成序列中的下一个数字。

由于在您的公式中,k必须将target划分为没有剩余,我们会得到k i&#39; s,其中每个i等于target / k - (k - 1)。你的公式还规定i是奇数。我们需要向2 k添加多少i来获取target

i = target / k - (k - 1)
multiply both sides by k
k * i = k * target / k - (k - 1) * k
k * i + (k - 1) * k = target

我们需要将(k - 1) * k / 2 2添加到k i以获取target。回顾我们的连续奇数序列的公式,我们看到这已经实现了:

target = k * i + (k - 1) * k 
       = k * i + 2 * (k - 1) * k / 2
       = k * i + 2 * p  where p is the pyramid number (k - 1) * k / 2

由于你的循环尝试了所有可能的i,我们保证会传递所有可能的连续奇数序列,它们总和为target