반응형
문제 설명
algospot.com :: BOARDCOVER
게임판 덮기 문제 정보 문제 H*W 크기의 게임판이 있습니다. 게임판은 검은 칸과 흰 칸으로 구성된 격자 모양을 하고 있는데 이 중 모든 흰 칸을 3칸짜리 L자 모양의 블록으로 덮고 싶습니다. 이
algospot.com
- 세로 H, 가로 W 크기의 게임판이 주어진다.
- 게임판은 검은 칸과 흰 칸으로 구성된다.
- 흰 칸 영역을 3칸짜리 ㄴ자 모양의 블록으로 덮고자 한다.
=> 모든 흰 칸을 덮을 수 있도록 블록을 배치하는 경우의 수를 출력하기
문제 풀기
이 문제는 전체 칸을 방문하면서, 흰 칸에서 ㄴ자 블록을 배치하는 코드를 구현해야 한다.
그 때,
1. 흰 칸에만 블록이 들어가도록 해야한다.
2. 전체를 돌았을 때 흰 칸이 남지 않아야 한다.
그러므로 왼쪽 상단에서 우측 하단까지 전체 칸을 방문하는데, 흰 칸을 만나면 거기서 배치할 수 있는 모양의 블록을 배치해주면 된다.
블록은 다음과 같은 4가지 경우로 놓을 수 있다.
이 4가지 경우에 해당하지 않을 경우, 전체 흰 칸을 채울 수 없으므로 더 진행할 필요가 없다.
또한 ㄴ블록은 3칸으로 이루어져 있는데,
전체 흰 칸의 개수가 3의 배수가 아니라면 블록을 놓아볼 필요도 없이 전부 채울 수 없으므로 0을 반환한다.
문제 풀이 코드
#include <iostream>
#include <string>
using namespace std;
int C, h, w;
char map[22][22];
int putBlock(int r, int c) {
if (r > h) {
return 1;
}
// 다음 좌표 값 계산
int nextR, nextC;
if (c == w) {
nextR = r + 1;
nextC = 0;
}
else {
nextR = r;
nextC = c + 1;
}
int cnt = 0;
// 흰 칸인 경우
if (map[r][c] == '.') {
if (map[r][c+1] == '.' && map[r + 1][c + 1] == '.') { // 오른쪽, 오른쪽아래
// 블록 놓기
map[r][c + 1] = '#';
map[r+1][c+1] = '#';
map[r][c] = '#';
cnt += putBlock(nextR, nextC);
// 블록 되돌리기
map[r][c + 1] = '.';
map[r + 1][c + 1] = '.';
map[r][c] = '.';
}
if (map[r + 1][c] == '.' && map[r + 1][c + 1] == '.') { // 아래, 오른쪽아래
map[r+1][c] = '#';
map[r + 1][c + 1] = '#';
map[r][c] = '#';
cnt += putBlock(nextR, nextC);
map[r+1][c] = '.';
map[r + 1][c + 1] = '.';
map[r][c] = '.';
}
if (map[r + 1][c] == '.' && map[r + 1][c - 1] == '.') { // 아래, 왼쪽아래
map[r + 1][c] = '#';
map[r + 1][c - 1] = '#';
map[r][c] = '#';
cnt += putBlock(nextR, nextC);
map[r + 1][c] = '.';
map[r + 1][c - 1] = '.';
map[r][c] = '.';
}
if (map[r + 1][c] == '.' && map[r][c + 1] == '.') { // 아래, 오른쪽
map[r + 1][c] = '#';
map[r][c + 1] = '#';
map[r][c] = '#';
cnt += putBlock(nextR, nextC);
map[r + 1][c] = '.';
map[r][c + 1] = '.';
map[r][c] = '.';
}
return cnt;
}
// 검은 칸인 경우
return putBlock(nextR, nextC);
}
int main() {
cin >> C;
for (int tc = 0; tc < C; ++tc) {
cin >> h >> w;
// 테두리 # 처리
for (int r = 0; r <= h; ++r) {
map[r][0] = map[r][w + 1] = '#';
}
for (int c = 0; c <= w; ++c) {
map[0][c] = map[h + 1][c] = '#';
}
// input
int whiteCount = 0;
string S;
for (int r = 1; r <= h; ++r) {
cin >> S;
for (int c = 1; c <= w; ++c) {
map[r][c] = S[c-1];
if (map[r][c] == '.') ++whiteCount;
}
}
// 흰 칸의 개수가 3의 배수가 아니면 모두 덮을 수 없다
if (whiteCount % 3 != 0) {
cout << 0 << endl;
}
else {
cout << putBlock(1,1) << endl;
}
}
return 0;
}
반응형
'알고리즘 문제풀이 > 알고리즘 문제해결전략' 카테고리의 다른 글
8.2_와일드 카드_WILDCARD (0) | 2023.02.12 |
---|---|
7.3_울타리 잘라내기_FENCE (0) | 2023.02.08 |
7.2_쿼드 트리 뒤집기_QUADTREE (0) | 2023.02.07 |
6.8_시계 맞추기_CLOCKSYNC (0) | 2023.01.20 |
6.3_소풍_PICNIC (0) | 2023.01.12 |