第八届蓝桥杯决赛 磁砖样式(枚举)
生活随笔
收集整理的這篇文章主要介紹了
第八届蓝桥杯决赛 磁砖样式(枚举)
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
標題:磁磚樣式
小明家的一面裝飾墻原來是 3*10 的小方格。
現在手頭有一批剛好能蓋住2個小方格的長方形瓷磚。
瓷磚只有兩種顏色:黃色和橙色。
小明想知道,對于這么簡陋的原料,可以貼出多少種不同的花樣來。
小明有個小小的強迫癥:忍受不了任何2?22*22?2的小格子是同一種顏色。
(瓷磚不能切割,不能重疊,也不能只鋪一部分。另外,只考慮組合圖案,請忽略瓷磚的拼縫)
顯然,對于 2?32*32?3個小格子來說,口算都可以知道:一共10種貼法,如【p1.png所示】
但對于3?103*103?10 的格子呢?肯定是個不小的數目,請你利用計算機的威力算出該數字。
注意:你需要提交的是一個整數,不要填寫任何多余的內容(比如:說明性文字)
答案:101466
分析
- 對于這道題,我們只要枚舉出所以的磁磚鋪設情況,統計出滿足要求的情況個數就能解出這道題了。但是怎么枚舉,如何判斷是否滿足要求,如何記錄當前滿足條件的鋪設情況。下面我們來解決這些問題:
我們先規定一種鋪設方式:先一行一行地鋪,當這當前行鋪滿了,再去鋪下一行。磁磚可以橫向鋪設,也可以豎向鋪設,我們可以分開寫成兩個部分,根據當前行剩余的空位來選擇橫向鋪設還是縱向鋪設。對于各個位置狀態的標記,如果沒有鋪設,該位置的狀態值為-1;如果鋪黃色,該位置的狀態值為0;如果橙色,該位置的狀態值為1。
只要任意2?22*22?2的小方格里面狀態值的和不為0和4就可以判斷為符合條件。
一共有30個位置,每個位置都只有兩種狀態(橙色或者黃色),我們可以用二進制來進行狀態記錄,然后把狀態值放進一個集合中(集合中的元素不會重復),最后把集合的大小輸出即可得到花樣總數。
代碼如下
import java.util.*;public class Main {final static int r=3,c=10;static int a[][]=new int [r][c];static Set<Integer> set=new HashSet<>();static boolean check() {for(int i=0;i<r-1;i++)for(int j=0;j<c-1;j++)if((a[i][j]+a[i+1][j]+a[i][j+1]+a[i+1][j+1])%4==0)return false;return true;}static void dfs(int x,int y) {if(a[x][y]==-1) {//橫向鋪設if(y+1<c && a[x][y+1]==-1) {for(int i=0;i<2;i++) {a[x][y]=a[x][y+1]=i;if(y==c-1) {dfs(x+1, 0);}else {dfs(x, y+1);}a[x][y]=a[x][y+1]=-1;//backtracking}}//豎向鋪設if(x+1<r && a[x+1][y]==-1) {for(int i=0;i<2;i++) {a[x][y]=a[x+1][y]=i;if(y==c-1) {dfs(x+1, 0);}else {dfs(x, y+1);}a[x][y]=a[x+1][y]=-1;//backtracking}}}else {if(y==c-1 && x==r-1) {if(check()) {int res=0;for(int i=0;i<r;i++)for(int j=0;j<c;j++) res=(res<<1)+a[i][j];set.add(res);}return;}//if there is still space leftif(y==c-1) {dfs(x+1, 0);}else {dfs(x, y+1);}}}public static void main(String[] args) {for(int i=0;i<r;i++)Arrays.fill(a[i], -1);dfs(0, 0);System.out.println(set.size());} }總結
以上是生活随笔為你收集整理的第八届蓝桥杯决赛 磁砖样式(枚举)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 第八届蓝桥杯决赛 平方十位数(枚举)
- 下一篇: 第八届蓝桥杯决赛 图书排列