题目:
A,2,3,4,5,6,7,8,9 共9张纸牌排成一个正三角形(A按1计算)。要求每个边的和相等。
下图就是一种排法(如有对齐问题,参看p1.png)。
A
9 6
4 8
3 7 5 8
这样的排法可能会有很多。
如果考虑旋转、镜像后相同的算同一种,一共有多少种不同的排法呢?
请你计算并提交该数字。
分析:
- 每个边相等,可以直接抽象转换为一个数字问题,只需要满足三条边,相对应位置上的数字相加相等且不重复就ok。
- 图形的问题是在于去重,旋转和镜像相同算同一种,这里可以直接由p1.png推导出,p1.png旋转和镜像(对称)可以满足6种相同,所以只需要在结果/3/2.
- 满足数的相加相等且不重复可以考虑两种方法 暴力/回溯,
这样有点类似于用1-9个数,来组成不重复的九位数,再选出我们需要的可能的数的数量
类似题目:
蓝桥杯JavaB组 3. 凑算式
代码:
答案: 144
1. 暴力
public static void bruteForce() {
int a, b, c, d, e, f, g, h, i;
int sum = 0;
int num = 0;//循环一共执行9^9次
for (a = 1; a < 10; a++) {
for (b = 1; b < 10; b++) {
for (c = 1; c < 10; c++) {
for (d = 1; d < 10; d++) {
for (e = 1; e < 10; e++) {
for (f = 1; f < 10; f++) {
for (g = 1; g < 10; g++) {
for (h = 1; h < 10; h++) {
for (i = 1; i < 10; i++) {
num++;
if (a + b + d + f == a + c + e + i
&& a + b + d + f == f + g + h + i
&& a != b
&& a != c && a != d
&& a != e && a != f
&& a != g && a != h
&& a != i
&& b != c
&& b != d && b != e
&& b != f && b != g
&& b != h && b != i
&& c != d && c != e
&& c != f && c != g
&& c != h && c != i
&& d != e && d != f
&& d != g && d != h
&& d != i && e != f
&& e != g && e != h
&& e != i && f != g
&& f != h && f != i
&& g != h && g != i
&& h != i) {
sum++;
}
}
}
}
}
}
}
}
}
}
System.out.println("暴力题目结果:"+sum/3/2);
System.out.println("暴力循环执行次数:"+num);
}
2.回溯
static int sum;
static int num;
static int arr[] = {1,2,3,4,5,6,7,8,9};
public static void backTracting(int k) {
if (k == 9) {
int x1 = arr[0] + arr[1] + arr[3] + arr[5];
int x2 = arr[0] + arr[2] + arr[4] + arr[8];
int x3 = arr[5] + arr[6] + arr[7] + arr[8];
if (x1 == x2 && x2 == x3)
sum++;
}
for (int i = k;i < 9;i++) {
//处理节点(此处交换数组的位置)
int t = arr[k];
arr[k] = arr[i];
arr[i] = t;
backTracting(k + 1);
t = arr[k];
//回溯处理节点(此处还原数组的位置)
arr[k] = arr[i];
arr[i] = t;
num++;
}
}
总结:
- 题的难度不大,是作为出现填空题,直接暴力全排列再选出满足要求的。
- 这里可以直接用暴力法但是注意检查if判断里的不等条件。
- 回溯法理解起来有点困难对于初学者,此处的回溯也是回溯算法的一个基本模板,要注意正如上述
类似于用1-9个数,来组成不重复的九位数
回溯要做的也正是这个意思,但是在数学上,可能性就是9的阶乘种,回溯的次数和它是不相等的,前者次数更多,这里如果有疑问可以用几个数推导一下。