剪邮票

题目描述

剪邮票
如【图1.jpg】, 有12张连在一起的12生肖的邮票。
现在你要从中剪下5张来,要求必须是连着的。
(仅仅连接一个角不算相连)
比如,【图2.jpg】,【图3.jpg】中,粉红色所示部分就是合格的剪取。
请你计算,一共有多少种不同的剪取方法。
请填写表示方案数目的整数。
注意:你提交的应该是一个整数,不要填写任何多余的内容或说明性文字。

在这里插入图片描述

思路

这题还是有一定难度的,解决此类问题,一般涉及到数学坐标分析的功底,乍一看我们能想到使用深搜,搜出5个满足连通的方格,存入Set集合自动判重,注意set里面存的不能为数组,只能是一个包装类或者集合,这里我们使用map去存5个方格,再放入set中

1.判断连通的条件

  • 从第一个方格开始,每一个方格必须与前几个方格中的一个相邻
    (局部连通构造全局连通,有点像动态规划)
  • 相邻的条件判断:数值相差为4,或数值相差为1(且两数必须在同一行)

代码

package competion2016;

import java.util.HashSet;
import java.util.LinkedList;
import java.util.Set;



public class 方格填数2 {

	static int arr[]=new int[5];
	  static int ants=0;
	  static Set<HashSet<Integer>> set=new HashSet<HashSet<Integer>>();
	  

	  static int visit[]=new int[13];
	
	public static void dfs(int x) {
		// TODO 自动生成的方法存根
		if(x==5) {//五个数找到了
			HashSet<Integer> hashSet=new HashSet<Integer>();
			for (int i = 0; i < 5; i++) {
				hashSet.add(arr[i]);
			}
			set.add(hashSet);
			return;
		}
		for (int i = 1; i <= 12; i++) {
			if (visit[i]==0&&check(x,i)) {
				visit[i]=1;
				arr[x]=i;
				dfs(x+1);
				visit[i]=0;
			}
			
		}
		
	}
	
	//判断前a[0],到a[x-1]中是否有元素和i相临,递归的分析
	public static boolean check(int x,int i) {
		
		if(x==0) {
			return true;
		}
		for (int k = 0; k < x; k++) {
			if(adjust(arr[k], i)) {
				return true;
			}
		}
		return false;
	}
	
	
	
	
	
	//判断两个数相邻
	public static boolean adjust(int x,int y) {
		
		int mid=Math.min(x,y);
        int max=Math.max(x,y);
        x=mid;
        y=max;
		if(y-x==4||(y-x==1&&x%4!=0)) {
			return true;
		}
		return false;
	}
	
	//深搜,且判断某点是否与前面的其中一个点相邻

	public static void main(String[] args) {
		// TODO 自动生成的方法存根

	 
	  dfs(0);
	  System.out.println(set.size());
	  
	  
	}
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值