方格填数
如下的10个格子
+--+--+--+
| | | |
+--+--+--+--+
| | | | |
+--+--+--+--+
| | | |
+--+--+--+
(如果显示有问题,也可以参看【图1.jpg】)
填入0~9的数字。要求:连续的两个数字不能相邻。
(左右、上下、对角都算相邻)
一共有多少种可能的填数方案?
请填写表示方案数目的整数。
注意:你提交的应该是一个整数,不要填写任何多余的内容或说明性文字。
public class Main{
public static int count = 0;
public static void swap(int[] A,int a,int b) {
int temp = A[a];
A[a] = A[b];
A[b] = temp;
}
public static boolean check(int[] A) {
if (Math.abs(A[0]-A[3])!=1 && Math.abs(A[0]-A[4])!=1 && Math.abs(A[0]-A[5])!=1 && Math.abs(A[0]-A[1])!=1){
if (Math.abs(A[1]-A[2])!=1 && Math.abs(A[1]-A[4])!=1 && Math.abs(A[1]-A[5])!=1 && Math.abs(A[1]-A[6])!=1){
if (Math.abs(A[2]-A[5])!=1 && Math.abs(A[2]-A[6])!=1) {
if (Math.abs(A[3]-A[4])!=1 && Math.abs(A[3]-A[7])!=1 && Math.abs(A[3]-A[8])!=1) {
if (Math.abs(A[4]-A[7])!=1 && Math.abs(A[4]-A[8])!=1 && Math.abs(A[4]-A[9])!=1 && Math.abs(A[4]-A[5])!=1){
if (Math.abs(A[5]-A[8])!=1 && Math.abs(A[5]-A[9])!=1 && Math.abs(A[5]-A[6])!=1) {
if (Math.abs(A[6]-A[9])!=1 && Math.abs(A[7]-A[8])!=1) {
if (Math.abs(A[8]-A[9])!=1) {
return true;
}
}
}
}
}
}
}
}
return false;
}
private static void dfs(int[] A, int step) {
if(step == A.length) {
if (check(A)) {
count++;
}return;
}else {
for (int i = step; i < A.length; i++) {
swap(A,i,step);
dfs(A, step+1);
swap(A,i,step);
}
}
return;
}
public static void main(String[] args) {
int[] A = {0,1,2,3,4,5,6,7,8,9};
dfs(A,0);
System.out.println(count);
}
}
方格填数和凑算式的解题思路都是将可能取到的数用一个数组装起来,然后对数组进行全排列,然后在递归调用中检验每种组合是否符合题意
如对{0,1,2,3,4,5,6,7,8,9}check检验,然后交换变成{0,1,2,3,4,5,6,7,9,8},check检验,复原{0,1,2,3,4,5,6,7,8,9},
交换成{0,1,2,3,4,5,6,8,7,9},check检验,此时在递归中继续压栈,继续交换成{0,1,2,3,4,5,6,8,9,7},check检验,
然后复原{0,1,2,3,4,5,6,8,7,9},再弹栈复原{0,1,2,3,4,5,6,7,8,9}......就这么一直交换和复原,其中过程有一些省略,
具体的可以自己画一个栈将每次调用的方法压栈出栈去理解,推导一下前面的过程就可以理解整个调用过程了,
它执行次数为全排列A1,1+A2,2+A3,3+A4,4+A5,5+A6,6+A7,7+A8,8+A9,9+A10,10的和。