最近看蓝桥杯的题目,有好多这种数学基本方式的题目,有些题目如果可以总结出公式或者是递推公式,就会很容易就能算出结果。这种全排列的题目,如果只是填空的话,不做提前判断减少分支的话,暴力破解等个一两分钟也能算出来。要是编程的话就需要更多的判断来减少时间开销了。
把待全排列记录分为两个部分:
(1) 确定第一位一个记录
(2) 剩下的所有元素
所有记录的全排列就是所有可能出现在第一个位置的记录与剩下所有元素的全排列。
以[1,2,3]为例,
1,2,3的全排列可以看作是
1,[2,3的全排列]
[2,3]的全排列又可以看作是
2,[3的全排列]—————对应123
3,[2的全排列]—————对应132
2,[1,3的全排列]
[1,3]的全排列又可以看作是
1,[3的全排列]—————对应213
3,[1的全排列]—————对应231
3,[1,2的全排列]
[1,2]的全排列又可以看作是
1,[2的全排列]—————对应312
2,[1的全排列]—————对应321
所以很明显,这就是一个递归的思想:给你部分记录,全排列就是所有可能出现在第一个位置的记录与剩下的元素的全排列,剩下的元素的全排列又是剩下的可能出现在第一个位置的元素与剩下的元素的全排列,依次重复下去….
分两个步骤:
下面以蓝桥杯的题目说一下全排列的实现
现在小学的数学题目也不是那么好玩的。
看看这个寒假作业:
□ + □ = □
□ - □ = □
□ × □ = □
□ ÷ □ = □
每个方块代表1~13中的某一个数字,但不能重复。
比如:
6 + 7 = 13
9 - 8 = 1
3 * 4 = 12
10 / 2 = 5
以及:
7 + 6 = 13
9 - 8 = 1
3 * 4 = 12
10 / 2 = 5
就算两种解法。(加法,乘法交换律后算不同的方案)
你一共找到了多少种方案?
请填写表示方案数目的整数。
注意:你提交的应该是一个整数,不要填写任何多余的内容或说明性文字。
package LanQiao;
public class 寒假作业 {
static int count = 0;
public static void main(String[] args) {
int[] a = {1,2,3,4,5,6,7,8,9,10,11,12,13};
dfs(a,0,12);
System.out.println(count);
}
//递归实现全排列
public static void dfs(int[] a, int start, int end) {
if (start == end) {
if (judge(a))
count++;
return;// 一次全排列
}
for (int i = start;i<=end;i++) {
swap(a, i, start);
dfs(a, start+1, end);
swap(a, i, start);//因为修改是对唯一的数组做了修改,为了不影响后续的排列,
//每一次会递归完成并回到这里时都要将交换复原
}
}
//交换两个数组值的位置
public static void swap(int a[],int i,int j) {
int temp = a[i];
a[i] = a[j];
a[j] = temp;
}
//判断是否符合
public static boolean judge(int a[]) {
if (a[1] + a[2] == a[3] && a[4] - a[5] == a[6] && a[7] * a[8] == a[9]
&& (a[10] / a[11] == a[12] && a[10] % a[11] == 0)) {// 必须判断余数为零
return true;
} else {
return false;
}
}
}
等待一段时间输出的结果是64