蓝桥杯Java B组之方格填数

方格填数

	如下的10个格子
	   +--+--+--+
	   |  |  |  |
	+--+--+--+--+
	|  |  |  |  |
	+--+--+--+--+
	|  |  |  |
	+--+--+--+
	
	(如果显示有问题,也可以参看【图1.jpg】)
	
	填入0~9的数字。要求:连续的两个数字不能相邻。
	(左右、上下、对角都算相邻)
	
	一共有多少种可能的填数方案?
	
	请填写表示方案数目的整数。
	注意:你提交的应该是一个整数,不要填写任何多余的内容或说明性文字。
public class Main{
	public static int count = 0;
	/*需求
	 * 方格填数
		如下的10个格子
		   +--+--+--+
		   |  |  |  |
		+--+--+--+--+
		|  |  |  |  |
		+--+--+--+--+
		|  |  |  |
		+--+--+--+
		
		(如果显示有问题,也可以参看【图1.jpg】)
		
		填入0~9的数字。要求:连续的两个数字不能相邻。
		(左右、上下、对角都算相邻)
		
		一共有多少种可能的填数方案?
		
		请填写表示方案数目的整数。
		注意:你提交的应该是一个整数,不要填写任何多余的内容或说明性文字。
	  */
	
	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的和。
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值