正方形圈

时间:2010-08-30 03:19:01

标签: java math

你可以将数字1到16排成一个圆圈,使相邻两个数字的总和成为一个完美的正方形吗?如果是,如何,如果不是,为什么不呢? 你能写一个程序来解决这个问题吗?

5 个答案:

答案 0 :(得分:8)

提示你。使用这组数字,只有一个可能的总和,其中16个构成一个完美的正方形(16 + 9 = 25),所以答案是否定的。

答案 1 :(得分:3)

[1,15,10,6,3,13,12,4,5,11,14,2,7,9,16]

是的,我可以写一个程序来解决它。

编辑:刚认识到这不是一个圆圈......这是唯一的线性解决方案,所以我的回答是:

不,不可能。

答案 2 :(得分:2)

答案是否定的 如果从16-> 1向后看16,16需要2个相邻数,则满足和为完美平方。但我们只能找到16 + 9 = 25,而不是更多。 (因为下一个是16或36,这两者都是不可能的)。 但是,如果问题变为线性而不是圆,那么将会有一个解决方案: 8,1,15,10,6,3,13,12,4,5,11,14,2,7,9,16 这是唯一可行的解​​决方案。

这里我附上了我的代码来解决线性版本:

import java.util.Arrays;

public class PerfectSquareLinear {
    public static final int MAX_NUMBER = 16;
    public static int[] square = { 1, 4, 9, 16, 25 };

    public static void main(String args[]) {
        new PerfectSquareLinear().go();
    }

    public boolean sumIsPerfectSquare(int a, int b) {
        return Arrays.binarySearch(square, a + b) < 0 ? false : true;
    }

    /**
     * 
     * @param l
     *            current result array
     * @param p
     *            position to fill in
     * @param pool
     *            available numbers
     */
    public void fill(int[] l, int p, int[] pool) {

        if (p > MAX_NUMBER - 1) {
            System.out.println(Arrays.toString(l));
        } else {
            for (int i = 0; i < MAX_NUMBER; i++) {
                if (pool[i] > 0) {
                    l[p] = pool[i];
                    if (p == 0 || sumIsPerfectSquare(l[p], l[p - 1])) {
                        pool[i] = -1;
                        fill(l, p + 1, pool);
                        pool[i] = i + 1;
                    } else {
                        // System.out.println("dead end: " +
                        // Arrays.toString(l));
                    }
                }
            }
        }
    }

    public void go() {
        // the result array for compute the permutation
        int[] list = new int[MAX_NUMBER];
        // the pool array to store the available number
        int[] pool = new int[MAX_NUMBER];
        // initial pool array
        for (int n = 1; n <= MAX_NUMBER; n++) {
            pool[n - 1] = n;
        }
        fill(list, 0, pool);
    }
}

答案 3 :(得分:1)

这可能是错的,但我似乎找不到使用此代码的可能周期:

/**
 * @author BjørnS
 * @created 30. aug. 2010
 */
public class PerfectSquares {

    /**
     * @param args
     */
    public static void main(String[] args) {

        List<Integer> options = Lists.newArrayList();

        for (int i = 1; i <= 16; i++) {
            options.add(i);
        }

        List<Integer> start = start(options);

        if (start == null) {
            System.out.println("Unsolvable unless this code is wrong.");
        } else {
            System.out.println("My answer is: " + start);
        }

    }

    private static List<Integer> start(List<Integer> options) {

        for (Integer i : options) {

            List<Integer> li = Lists.newArrayList(options);
            li.remove(i);

            List<Integer> ws = Lists.newArrayList(i);

            List<Integer> answer = findAnswer(ws, li);
            if (answer != null) {
                return answer;
            }
            ws = null;
            li = null;
        }

        return null;

    }

    private static List<Integer> findAnswer(List<Integer> workingSet, List<Integer> options) {

        Integer last = workingSet.get(workingSet.size() - 1);

        if (options.size() == 1) {

            Integer first = workingSet.get(0);

            Integer option = options.get(0);

            if (isPerfectSquare(first, option) && isPerfectSquare(last, option)) {
                workingSet.add(option);
                System.out.println("I think it is:" + workingSet);
                return workingSet;
            }
            return null;
        }

        for (Integer i : options) {

            if (isPerfectSquare(last, i)) {

                List<Integer> li = Lists.newArrayList(options);
                li.remove(i);

                List<Integer> ws = Lists.newArrayList(workingSet);
                ws.add(i);

                System.out.println("trying " + ws);

                List<Integer> answer = findAnswer(ws, li);
                if (answer != null) {
                    System.out.println("Potential answer:" + answer);
                    return ws;
                }

                li = null;
                ws = null;

            }

        }

        return null;
    }

    private static boolean isPerfectSquare(Integer a, Integer b) {

        return Math.pow(Math.floor(Math.sqrt(a + b)), 2) == (a + b);

    }

}

答案 4 :(得分:0)

如果您考虑具有顶点1,2,...,16和边(a,b)的图形,如果a + b是方形,则问题等同于在此图上查找哈密顿路径。 / p>

找到哈密尔顿路径一般是NP,这表明你不会比搜索更好。