你可以将数字1到16排成一个圆圈,使相邻两个数字的总和成为一个完美的正方形吗?如果是,如何,如果不是,为什么不呢? 你能写一个程序来解决这个问题吗?
答案 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,这表明你不会比搜索更好。