蓝桥杯 决赛 2017 C++B(2)瓷砖样式 dfs + hash去重

标题:磁砖样式

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

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


思路:dfs + 去重

答案:101466
 
  
#include<stdio.h> #include<string.h> #include<stdlib.h> #include<map> using namespace std;
int mp[4][11]; map<int,int> hash; int tol;
bool noSame()//判断是否存在4个方块同样  {   for(int i = 1; i <= 2; ++i){    for(int j = 1; j <= 9; ++j){     if(mp[i][j] == mp[i+1][j] && mp[i+1][j] == mp[i][j+1] && mp[i][j+1] == mp[i+1][j+1])      return false;    }   }   return true;  }   void color(int x, int y, int type,int v)//根据type判断水平2块还是数值2块  染成 v  {   if(type == 1){ //水平    for(int i = x; i < x+1; ++i){     for(int j = y; j < y+2; ++j){      mp[i][j] = v;     }    }   }   else if(type == 2){    for(int i = x; i < x+2; ++i){     for(int j = y; j < y+1; ++j){      mp[i][j] = v;     }    }   }  } bool checkX(int x, int y)//判断X方向是否能放2块  {   if(x+1 > 3 || y > 10)    return false;   for(int i = x; i < x+2; ++i){    for(int j = y; j < y+1; ++j){     if(mp[i][j])      return false;    }   }   return true;  }   void output()  {   for(int i = 1; i <= 3; ++i){    for(int j = 1; j <= 10; ++j){     printf("%d",mp[i][j]);    }    printf("\n");   }  } 
bool checkY(int x, int y)//判断y方向能否放2块  {   if(x > 3 || y+1 > 10)    return false;   for(int i = x; i < x+1; ++i){    for(int j = y; j < y+2; ++j){     if(mp[i][j])      return false;    }   }    return true;  }   void dfs(int x, int y)  {   if(x > 3){    if(noSame()){     int bit = 1;     long long ans = 0;     for(int i = 1; i <= 3; ++i){      for(int j = 1; j <= 10; ++j){       ans += bit*mp[i][j];       bit <<= 1;      }     }     if(!hash[ans]){      ++tol;      ++hash[ans];     }    }    return ;   }    if(mp[x][y] == 0){    if(checkX(x,y)){     for(int i = 1; i <= 2; ++i){//注意瓷砖有2种 可以染不同颜色      color(x,y,2,i);      if(y == 10){       dfs(x+1,1);      }      else{       dfs(x,y+1);      }      color(x,y,2,0);     }    }    if(checkY(x,y)){     for(int i = 1; i <= 2; ++i){      color(x,y,1,i);      if(y == 10){       dfs(x+1,1);      }      else{       dfs(x,y+1);      }      color(x,y,1,0);     }    }   }   else{    if(y == 10){     dfs(x+1,1);    }    else{     dfs(x,y+1);    }   }  }
int main()  {   memset(mp,0,sizeof(mp));   dfs(1,1);   printf("%d",tol);      return 0;  }



猜你喜欢

转载自blog.csdn.net/tianweidadada/article/details/80428062
今日推荐