蓝桥杯国赛8-JavaA-2-瓷砖样式

本文介绍了一个使用深度优先搜索算法(DFS)结合去重方法解决的问题:计算特定条件下不同瓷砖样式数量的方法。对于3×10的网格,每两个相邻单元格可以被黄色或橙色的瓷砖覆盖,且不允许出现2×2相同颜色的区域。通过递归搜索所有可能的排列并检查重复,最终得出有效的瓷砖布局总数。

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

import java.util.HashMap;

/*
 * 
小明家的一面装饰墙原来是 3*10 的小方格。
现在手头有一批刚好能盖住2个小方格的长方形瓷砖。
瓷砖只有两种颜色:黄色和橙色。

小明想知道,对于这么简陋的原料,可以贴出多少种不同的花样来。
小明有个小小的强迫症:忍受不了任何2*2的小格子是同一种颜色。
(瓷砖不能切割,不能重叠,也不能只铺一部分。另外,只考虑组合图案,请忽略瓷砖的拼缝)
显然,对于 2*3 个小格子来说,口算都可以知道:一共10种贴法,如【p1.png所示】

但对于 3*10 的格子呢?肯定是个不小的数目,请你利用计算机的威力算出该数字。

注意:你需要提交的是一个整数,不要填写任何多余的内容(比如:说明性文字)
 * */
public class T2_磁砖样式 {
	static int[][] array = new int[3][10];
	
	static int sum = 0;
	
	static HashMap<String, Integer> map = new HashMap<>();
	
	static boolean check() {
		for (int i = 0; i < array.length-1; i++) {
			for (int j = 0; j < array[0].length-1; j++) {
				int a = array[i][j];
				int b = array[i+1][j];
				int c = array[i][j+1];
				int d = array[i+1][j+1];

				if(a==b&&c==d&&a==c) {
					return false;
				}
			}
		}
		
		String result = "";
		for (int i = 0; i < array.length; i++) {
			for (int j = 0; j < array[0].length; j++) {
				result += array[i][j];
			}
		}
		
		// 以下判断有没有该序列之前有没有出现过
		if(map.get(result)!=null) {
			for (int i = 0; i < array.length; i++) {
				for (int j = 0; j < array[0].length; j++) {
					System.out.print(array[i][j]+",");
				}
				System.out.println();
			}
			System.out.println("*******************************");
		}
		map.put(result, 1);
		
		return true;
	}
	
	static void f(int num,int y,int x) {
		// 已经被填满
		if(num == (array.length*array[0].length)/2) {
			if(check()) {
				sum++;
			}
			return;
		}
		
		// 遍历一行结束判断
		if(x == array[0].length) {
			y = y+1;
			x = 0; 
		}
		
		// 判断是否越界
		if(y == array.length) {
			return;
		}
		
		// 已经被填充过
		if(array[y][x] != 0) {
			f(num,y,x+1);
			return;
		}
		
		// 1 为黄色,2为橙色
		for (int k = 1; k <= 2; k++) {
			// 横向
			// 判断x是否出界
			// 判断x的下一个是否出界
			if(x <= array[0].length -2) {
				// 判断下一格是否被染色
				if(array[y][x+1] == 0) {
					array[y][x] = k;
					array[y][x+1] = k;
					
					f(num+1,y,x+2);
					
					array[y][x] = 0;
					array[y][x+1] = 0;
				}
			}
			// 纵向
			if(y <= array.length -2) {
				// 判断竖直方向上下一格是否被染色
				if(array[y+1][x] == 0) {
					array[y][x] = k;
					array[y+1][x] = k;
					
					f(num+1,y,x+1);

					array[y][x] = 0;
					array[y+1][x] = 0;
				}
			}
		}
		
	}
	public static void main(String[] args) {
		
		f(0,0,0);
		
		System.out.println(sum); // 错误答案,没有去重
		System.out.println(map.size());	// 正确答案
		
	}
}
// 101466
/*
 * 思路:dfs+去重
 * 从第一个开始深度优先搜索遍历每一个坐标
 * 1. 如果被填充跳过
 * 2. 没被填充考虑两种情况,横向填充,纵向填充,
 * 3. 临界条件:当跳出数组范围,或填充满的时候结束进行判断是否有2*2是同一种颜色
 * 问题:去重
2,2,2,2,2,2,2,2,2,2,
2,1,1,2,1,1,2,1,1,2,
2,2,2,2,2,2,2,2,2,2,
例如上矩阵有 两种不同的瓷砖摆放方法
 * */
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值