题目:
请将8个给定的正整数(如1,2,3,4,5,6,7,8)分别放在一个正方体的8个角的顶点上,以实现如下要求(如果可能):正方体六个面上的四个角点整数之和相等?输出结果如:A1=1,A2=2...
求解如下

算法思路
根据题境,我们先做如下设定和术语说明,以便于后面的讨论:
1、正整数以1,2,3,4,。。。8表示,以便进行分析;
2、正方体顶点标示如上所示;
3、每一个面的四个顶点数总和,我们称为该面的面积;
4、每一条边的两个顶点数和,我们称为该边的长度;
通过分析,可以得到如下断言为真(采用上面设定及术语):
1、每个面的面积相等,且每个面的面积为36/2,即18;
2、正方体的对边相等,如A1A2=A7A8、A2A6=A3A7等等;
3、整数1和(2,3)不在同一边,整数7和8不在同一边;
根据所得断言,可以得到如下求导公式和约束:
A1=1;
A4=18-A1-A2-A3=17-A2-A3;
A6=18-A1-A2-A5=17-A2-A5;
A7=18-A1-A3-A5=17-A3-A5;
A8=A1+A2-A7=2*A1+A2+A3+A5-18=A2+A3+A5-16;
A2,A3,A5为可变量,但是A2,A3,A5不等于2,3
程序实现
通过以上算法分析,可用程序实现如下(Java实现):
java 代码
- package qinysong.arithmetic;
-
- public class CubeProblem {
-
- public static void main(String[] args) {
- System.out.println("CubeProblem begin ........");
- searchPeekNumber();
- System.out.println("CubeProblem end ........");
- }
-
- public static void printPeekNumbers(int[] peeks){
- System.out.println("the peek number:A1=" + peeks[0] + ";A2=" + peeks[1]
- + ";A3=" + peeks[2] + ";A4=" + peeks[3]
- + ";A5=" + peeks[4] + ";A6=" + peeks[5]
- + ";A7=" + peeks[6] + ";A8=" + peeks[7]);
- }
-
-
- public static void searchPeekNumber(){
- int[] peeks = new int[8];
- int peekNumber = 0;
- for (int i=4; i<=8; i++){
- peeks[0] = 1;
- peeks[1] = i;
- for (int j=4; j<=8; j++){
- if (hasUsed(2,j, peeks)) continue;
- peeks[2] = j;
- peekNumber = getPeekNumber(3, peeks);
- peeks[3] = peekNumber;
- for (int k=4; k<=8; k++){
- if (hasUsed(4,k, peeks)) continue;
- peeks[4] = k;
- peekNumber = getPeekNumber(5, peeks);
- if (hasUsed(5,peekNumber, peeks)) continue;
- peeks[5] = peekNumber;
- peekNumber = getPeekNumber(6, peeks);
- if (hasUsed(6,peekNumber, peeks)) continue;
- peeks[6] = peekNumber;
- peekNumber = getPeekNumber(7, peeks);
- if (hasUsed(7,peekNumber, peeks)) continue;
- peeks[7] = peekNumber;
- printPeekNumbers(peeks);
- }
- }
- }
- }
-
-
-
-
-
-
-
- public static boolean hasUsed(int index, int peekNumber,int[] peeks){
- if (peekNumber <= 0) return true;
- for (int i=0; i<index; i++){
- if (peeks[i] == peekNumber){
- return true;
- }
- }
- return false;
- }
-
-
-
-
-
-
-
-
-
- public static int getPeekNumber(int peek, int[] peeks) {
- switch (peek) {
- case 0:
- return 1;
- case 3:
- return 17 - peeks[1] - peeks[2];
- case 5:
- return 17 - peeks[1] - peeks[4];
- case 6:
- return 17 - peeks[2] - peeks[4];
- case 7:
- return peeks[1] + peeks[2] + peeks[4] - 16;
- default:
- return 0;
- }
- }
- }
算法特性:
因为该算法是根据分析问题的数学模型,找到路径规律,然后直接推导答案,而不是采用通过遍历每一种可能性进行判断,所以效率比较好