蓝桥杯——瓷砖样式(第八届决赛)

标题:磁砖样式

小明家的一面装饰墙原来是 3*10 的小方格。
现在手头有一批刚好能盖住2个小方格的长方形瓷砖。
瓷砖只有两种颜色:黄色和橙色。
小明想知道,对于这么简陋的原料,可以贴出多少种不同的花样来。
小明有个小小的强迫症:忍受不了任何2*2的小格子是同一种颜色。
(瓷砖不能切割,不能重叠,也不能只铺一部分。另外,只考虑组合图案,请忽略瓷砖的拼缝)
显然,对于 2*3 个小格子来说,口算都可以知道:一共10种贴法,如【p1.png所示】
但对于 3*10 的格子呢?肯定是个不小的数目,请你利用计算机的威力算出该数字。

注意:你需要提交的是一个整数,不要填写任何多余的内容(比如:说明性文字)

样例


思路:dfs搜索,最后利用HashSet判重。

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

public class 瓷砖样式 {

	/**
	 * @param args
	 */
//	static int sum=0;
	static int dir[][]={{-1,0},{0,1},{1,0},{0,-1}};
	static Set<String> set=new HashSet<String>();
	public static void main(String[] args) {
		int x[][]=new int[3][10];
		for (int i = 0; i < x.length; i++) {
			for (int j = 0; j < x[0].length; j++) {
				x[i][j]=-1;
			}
		}
		dfs(x,0,0);
		System.out.println(set.size());
	}
	private static void dfs(int[][] x, int h, int l) {
		if(h>=x.length){
			if(check(x)){
//				sum++;
				String s="";
				for (int i = 0; i < x.length; i++) {
					for (int j = 0; j < x[0].length; j++) {
						s+=x[i][j]+"";
					}
				}
				set.add(s);
				return;
			}else {
				return;
			}
		}else{
		if(x[h][l]==-1) {//该点没有访问过
			for (int i = 0; i <= 1; i++) {
				x[h][l]=i;//填数   0或1
				//四个方向,分别试探填数
				for (int k = 0; k < 4; k++) {
					int x1=h+dir[k][0];
					int y1=l+dir[k][1];
					if(x1<0 || x1>=x.length || y1<0 || y1>=x[0].length){
						continue;
					}else if(x[x1][y1]!=-1){
						continue;
					}else {
						x[x1][y1]=i;
						//这里向下递归应该用(h,l)而不是(x1,y1),卡了bug。。。
						dfs(x,h+(l+1)/x[0].length,(l+1)%x[0].length);
						x[x1][y1]=-1;
					}
				}
				x[h][l]=-1;
			}
		}else {//访问过并且已经填了数
			dfs(x,h+(l+1)/x[0].length,(l+1)%x[0].length);
		}
	}
}
	
	private static boolean check(int[][] x) {
		for (int i = 1; i < x[0].length-1; i++) {
			if(judge(x,i)){
				return false;
			}
		}
		return true;
	}
	//检验是否出现小正方形的情况
	private static boolean judge(int[][] x, int j) {
		int t=x[1][j];
		if(x[1][j-1]==t&&x[0][j]==t&&x[0][j-1]==t){
			return true;
		}else if (x[1][j-1]==t&&x[2][j]==t&&x[2][j-1]==t) {
			return true;
		}else if (x[1][j+1]==t&&x[0][j]==t&&x[0][j+1]==t) {
			return true;
		}else if (x[1][j+1]==t&&x[2][j]==t&&x[2][j+1]==t) {
			return true;
		}
		return false;
	}

}




猜你喜欢

转载自blog.csdn.net/qq_39020387/article/details/80025887