现在手头有一批刚好能盖住2个小方格的长方形瓷砖。
瓷砖只有两种颜色:黄色和橙色。
//240ms
//ans = 114434
#include <iostream>
#include <cstring>
#include <ctime>
using namespacestd;
int mp[5][12];
int ans = 0;
const int m4[][2] = {{1,0},{0,1},{1,1}};
const int put2[][2] = {{0,1},{1,0}};
bool checkrange(int x,int y)
{
if (x <1 || x > 3 || y <1 || y > 10) {
returnfalse;
}
returntrue;
}
bool check4(int x,int y)//颜色不相同返回false,相同返回true
{
for (int i =0; i < 3; i ++) {
int tx = x +m4[i][0],ty = y +m4[i][1];
if (mp[x][y] !=mp[tx][ty]) {//如果tx,ty超范围,对2*2是否重色都不影响,所以不用判断。
returnfalse;
}
}
returntrue;
}
bool checkpos(int x,int y,int hv,int c)
{
bool fg =true;
int tx = x +put2[hv][0],ty = y +put2[hv][1];
if (!checkrange(tx, ty)) {//但是在拼瓷砖即为mp赋值时,需要注意不能贴到范围以外。
returnfalse;
}
if (mp[tx][ty] !=0) {//如果tx,ty已贴瓷砖,则不能重复贴
fg = false;
}
else {
mp[x][y] = c;
mp[tx][ty] = c;
for (int i = x -1; i <= x; i ++) {
for (int j = y -1; j <= y; j ++) {
if (check4(i, j)) {//如果有重色,则不行
fg = false;
}
}
}
mp[x][y] =mp[tx][ty] = 0;
}
return fg;
}
bool checkmap(){
for (int i =1; i <= 3; i ++) {
for (int j =1; j <= 10; j ++) {
if (mp[i][j] ==0) {
returnfalse;
}
}
}
returntrue;
}
void dfs(){
if(checkmap()){//如果整面墙都贴了瓷砖,计数
ans++;
return;
}
for(int i=1;i<=3;i++){
for(int j=1;j<=10;j++){//枚举可开始贴瓷砖的点,从左上向右下贴
if(mp[i][j]==0){//如果该点可以贴
for (int c =1; c <= 2; c ++) {//颜色
for (int hv =0; hv <= 1; hv ++) {//横着贴,或者竖着贴
if(checkpos(i, j, hv, c))
{
int tx = i +put2[hv][0],ty = j +put2[hv][1];
mp[i][j] = c;
mp[tx][ty] = c;
dfs();
mp[i][j] =0;
mp[tx][ty] =0;
}
}
}
return;
}
}
}
return;
}
int main() {
memset(mp,0, sizeof(mp));
dfs();
cout <<ans << endl;
return0;
}