贴瓷砖

小明家的一面装饰墙原来是 3*10 的小方格。
现在手头有一批刚好能盖住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]) {//如果txty超范围,对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) {//如果txty已贴瓷砖,则不能重复贴

        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;

}



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值