2017第八届蓝桥杯决赛(大学B组)java试题 瓷砖样式

标题:磁砖样式

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

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


思路还是DFS实现,没什么特别难的点,如果有错误,请指出。



package laoqiaobeijuesai;

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

public class 磁砖样式 {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		
		//答案是101466 需要去重
		int [] [] d =new int[3][l];
		run(d,0,0);
		System.out.println(sum);
		System.out.println(m.size());
	}
	static Set<String> m =new HashSet<String >();
	static int sum =0;
	static int l =10;
	
	public static void p(int [][] d){
		String a="";
		for(int i=0;i<3;i++){
			for(int j=0;j<l;j++){
				a+=d[i][j];
			}
		}
		m.add(a);
		
	}
	
	public static boolean cc( int [][] d, int x,int y){
		if(x>=1&&d[x][y]==d[x-1][y]){
			if(y>=1&&d[x][y-1]==d[x][y]&&d[x-1][y-1]==d[x][y]){
				return false;
			}
			if(y<l-1&&d[x][y+1]==d[x][y]&&d[x-1][y+1]==d[x][y]){
				return false;
			}
		}
		if(x<2&&d[x][y]==d[x+1][y]){
			if(y>=1&&d[x][y-1]==d[x][y]&&d[x+1][y-1]==d[x][y]){
				return false;
			}
			if(y<l-1&&d[x][y+1]==d[x][y]&&d[x+1][y+1]==d[x][y]){
				return false;
			}
		}
		return true;
	}

	public static void run(int [][] d, int x,int y){
		
		while(y>l-1||d[x][y]!=0){
			//y已经超出边界了  因为+1、2了
			//我就需要换行处理
			if(y<l&&d[x][y]!=0){
				y++;
				continue;
			}
			x=x+1;
			y=0;
			if(x>2){
				sum ++;
				p(d);
				System.out.println();
				return;
			}
			while(d[x][y]!=0){
				y++;
				if(y>l-1){
					break;
				}
			}
		}

		
		
		//竖着放一个11 或者22
		if(x<2){
			//11填充
			d[x][y]=1;
			d[x+1][y]=1;
			if(cc(d,x,y)&&cc(d,x+1,y)){
				//都能装的时候
				//指针右移
				run(d,x,y+1);
			}

			//22填充
			d[x][y]=2;
			d[x+1][y]=2;
			if(cc(d,x,y)&&cc(d,x+1,y)){
				//都能装的时候
				//指针右移
				run(d,x,y+1);
			}
			//回溯
			d[x][y]=0;
			d[x+1][y]=0;

		}
		//横着放一个11或者22
		if(y<l-1&&d[x][y+1]==0){
			//11填充
			d[x][y]=1;
			d[x][y+1]=1;

			if(cc(d,x,y)&&cc(d,x,y+1)){
				//都能装的时候
				//指针右移
				run(d,x,y+2);
			}
			//22填充
			d[x][y]=2;
			d[x][y+1]=2;
			if(cc(d,x,y)&&cc(d,x,y+1)){
				//都能装的时候
				//指针右移
				run(d,x,y+2);
			}
			//回溯
			d[x][y]=0;
			d[x][y+1]=0;
		}
	}

}


评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值