티스토리 뷰

Algorithm/ALGOSPOT

BOARDCOVER

henry1214 2021. 6. 7. 11:51

https://algospot.com/judge/problem/read/BOARDCOVER

 

algospot.com :: BOARDCOVER

게임판 덮기 문제 정보 문제 H*W 크기의 게임판이 있습니다. 게임판은 검은 칸과 흰 칸으로 구성된 격자 모양을 하고 있는데 이 중 모든 흰 칸을 3칸짜리 L자 모양의 블록으로 덮고 싶습니다. 이

algospot.com

 

완전탐색 문제이다. 그런데 경우의 수를 어떻게 중복없이 체계적으로 셀 수 있을까? 순서를 강제하면 된다.

게임판의 빈 부분을 좌상단부터 하나씩 채워나간다. 이 때 모든 빈 부분이 덮어지면 경우의 수를 하나 더해준다.

아래 그림에서 별표 부분을 덮는다고 가정하자. 이 때 별표 왼쪽 부분까지는 다 채워져 있다. 그러면 L자 모양의 블록을 덮는 경우가 4가지이고 모두 가능한지 확인해보면 된다. delta에 따라 블록을 덮거나 치울 수 있다.

 

 

#include <cstdio>

int t,h,w,map[55][55];
char tmap[55][55];
int coverType[4][3][2]={
    {{0,0},{1,0},{0,1}},
    {{0,0},{0,1},{1,1}},
    {{0,0},{1,0},{1,1}},
    {{0,0},{1,0},{1,-1}}
};

bool set(int x,int y,int type,int delta)
{
    bool ok=true;
    for(int i=0;i<3;i++)
    {
        int nx=x+coverType[type][i][0];
        int ny=y+coverType[type][i][1];
        if(nx<0 || nx>=h || ny<0 || ny>=w || (map[nx][ny]+=delta)>1)
            ok=false;
    }
    return ok;
}

int cover()
{
    int x=-1,y=-1;
    for(int i=0;i<h;i++)
    {
        for(int j=0;j<w;j++)
        {
            if(map[i][j]==0)
            {
                x=i,y=j;
                break;
            }
        }
        if(x!=-1 && y!=-1) break;
    }
    if(x==-1 && y==-1) return 1;
    int ret=0;
    for(int type=0;type<4;type++)
    {
        if(set(x,y,type,1))
            ret+=cover();
        set(x,y,type,-1);
    }
    return ret;
}

int main()
{
    scanf("%d",&t);
    while(t--)
    {
        scanf("%d %d",&h,&w);
        for(int i=0;i<h;i++)
            scanf("%s",tmap[i]);
        for(int i=0;i<h;i++)
            for(int j=0;j<w;j++)
                map[i][j]=(tmap[i][j]=='#')?1:0;
        printf("%d\n",cover());
    }
    return 0;
}

'Algorithm > ALGOSPOT' 카테고리의 다른 글

QUADTREE  (0) 2021.06.07
CLOCKSYNC  (0) 2021.06.07
PICNIC  (0) 2021.06.07
BOGGLE  (0) 2021.06.07
FESTIVAL  (0) 2018.06.15
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday