题目
标题:纸牌三角形
A,2,3,4,5,6,7,8,9 共9张纸牌排成一个正三角形(A按1计算)。要求每个边的和相等。
下图就是一种排法(如有对齐问题,参看p1.png)。
A
9 6
4 8
3 7 5 2
这样的排法可能会有很多。
如果考虑旋转、镜像后相同的算同一种,一共有多少种不同的排法呢?
请你计算并提交该数字。
注意:需要提交的是一个整数,不要提交任何多余内容。
考察
全排列+递归
分析
- 类似于五星填数问题,利用数组将三角形每个位置编号,题目就变成了数组元素排列问题;
- 通过计算每条边的和判断每条边是否相等,每有一次相等的结果,count++;
- 数组元素位置如图所示。
注意
- 回溯。每次进行完一次全排列后数组要重新初始化,避免排列之后变乱;
- 输出结果要除以(3*2)。三角形三条边,每条边都有两种相同的排列。
代码
public class 纸牌三角形 {
static int [] numArr;
static int count = 0;
public static void main(String[] args) {
numArr = new int[]{1,2,3,4,5,6,7,8,9};
int result = f(numArr,0);
System.out.println(result/(3*2));//除以3*2的原因:排除旋转,镜像的情况。
}
private static int f(int[] numArr, int i) {
// 递归出口
if (i==9) {
if (check()) {
count++;
}
}
for (int j = i; j < numArr.length; j++) {
int temp = numArr[i];
numArr[i] = numArr[j];
numArr[j] = temp;
f(numArr, i+1);
//!!!回溯,每次完成一次全排列之后要重新变为初始数组,从起点开始。
temp = numArr[i];
numArr[i] = numArr[j];
numArr[j] = temp;
}
return count;
}
/**
* 判断三角形三条边是否相等
* @return true 相等; false 不等
*/
private static boolean check() {
int a1 = numArr[0] + numArr[1] + numArr[3] + numArr[5];
int a2 = numArr[0] + numArr[2] + numArr[4] + numArr[8];
int a3 = numArr[5] + numArr[6] + numArr[7] + numArr[8];
if (a1==a2 && a2==a3) {
return true;
}
return false;
}
}