第七届蓝桥杯Java B组-剪邮票

本文介绍了一种用于判断五块拼图是否能通过连接形成有效图形的算法。该算法通过构建二维布尔数组来模拟拼图的状态,并使用递归方法生成所有可能的组合。通过对每个组合进行特定条件下的有效性验证,最终统计出符合条件的拼图数量。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

import java.util.Arrays;

public class Main{
	private static final int NEED = 5;
	private static final int ROW = 5;
	private static final int COL = 6;
	private static boolean [][]map = new boolean[ROW][COL];
	private static int cnt = 0;
	
	public static void judgeConnect(String s) {
		int sum = 0, flag = 0, sign = 0;
		for(int i = 1; sum != 5 && i < ROW - 1; ++i) {
			for(int j = 1; sum != 5 && j < COL - 1; ++j) {
				if(map[i][j]) {
					++sum;
					if(!map[i - 1][j] && !map[i + 1][j] && !map[i][j - 1] && !map[i][j + 1]) return;
					else if(sign < 2){ 
//如果发现此时sign已经大于2了,说明已经具备可以连成图的条件,就不必再判断,提高效率
						flag = 0;
						if(map[i - 1][j]) ++flag;
						if(map[i + 1][j]) ++flag;
						if(map[i][j - 1]) ++flag;
						if(map[i][j + 1]) ++flag;
/**
* 这一句是特判,会出现十字架的情况,十字架只有一个方块与其他四个相连,
* 其余四个都没有和另外两个方块相连。这就的我的解题思路的漏洞。没有写这句,打印114;最后又补上的这句
* */
						if(flag == 4) { sign = 4; sum = 5; }
/**
* 解题的思路:
* 通过观察图形发现,如果是五个方块相连的图形,至少要有两个方块的周围与另外两个方块相邻。
* 这包括:1、有三个方块与另外两个相连的,如可以拉成一条直线型的;如样例中:2、6、7、11、12中的6、7、11
* 2、有两个方块与另外两个相连的,如样例中:3、5、6、7、10的6、7两个方块
* */
						if(flag >= 2) ++sign;
					}
				}
			}
		}
		if(sign >= 2)++cnt;
	}
	
	public static void fillNum(String s) {
		if(s.contains("A")) map[1][1] = true;
		if(s.contains("B")) map[1][2] = true;
		if(s.contains("C")) map[1][3] = true;
		if(s.contains("D")) map[1][4] = true;
		if(s.contains("E")) map[2][1] = true;
		if(s.contains("F")) map[2][2] = true;
		if(s.contains("G")) map[2][3] = true;
		if(s.contains("H")) map[2][4] = true;
		if(s.contains("I")) map[3][1] = true;
		if(s.contains("J")) map[3][2] = true;
		if(s.contains("K")) map[3][3] = true;
		if(s.contains("L")) map[3][4] = true;
		judgeConnect(s);
	}
	/**
	 * 递归的写法,从13个方块中随机抽取5个方块。写法抄袭了这题的上一题的填空写法。
	 * 该段代码改编来自:蓝桥杯第七届Java B组的填空题
	 * */
	public static void fun(int []arr, int pos, int n, String s) {
		if(pos == arr.length) {
			if(0 == n) { for(boolean []item: map)Arrays.fill(item, false); fillNum(s); }
			return;
		}
		String str = s;
		for(int i = 0; i <= arr[pos]; ++i) {
			fun(arr, pos + 1, NEED - str.length(), str);
			str += (char)(pos + 'A');
		}
	}
	
	public static void main(String[] args) {
		int []arr= { 1,1,1,1,1,1,1,1,1,1,1,1 };
		fun(arr, 0, NEED, "");
		System.out.println(cnt);
	}
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值