250x250
Notice
Recent Posts
Recent Comments
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | ||||||
2 | 3 | 4 | 5 | 6 | 7 | 8 |
9 | 10 | 11 | 12 | 13 | 14 | 15 |
16 | 17 | 18 | 19 | 20 | 21 | 22 |
23 | 24 | 25 | 26 | 27 | 28 |
Tags
- 중복조합
- 알고리즘
- 순열
- 완탐
- 자바
- 코테
- 주사위굴리기2
- Bfs와DFS
- 자바 코테
- 23288
- 정올 1620
- 볼륨 만들기
- 백준
- 중복순열
- 에라토스테네스의채
- 완전탐색
- D드라이브생성
- 파티션 크기 조정
- 알고리즘개념
- java
- 백준15652
- 재귀함수
- 백준2251
- 전화번호속의암호
- 코테준비
- 정보처리기사
- 삼성역테
- N과M
- 백준13458
- BFS
Archives
- Today
- Total
뚱땅뚱땅
[알고리즘] 알고스팟 BOARDCOVER 문제 본문
728x90
# 알고리즘을 통한 문제 해결전략 6.5
- 이차원 벡터를 처음 사용해봤다!!
- 코드에 대한 이해가 더 필요하다.. 한번 더 풀어볼 것!
#include <iostream>
#include <vector>
using namespace std;
//주어진 칸을 덮을 수 있는 네가지 방법
// 블록을 구성하는 세 칸의 상대적 위치(dy,dx)의 목록
const 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 } }
};
//board(y,x)를 type번 방법으로 덮거나, 덮었던 블록을 없앤다.
//delta=1이면 덮고, -1이면 덮었던 블록을 없앤다
//만약 블록이 제대로 덮이지 않은 경우(겹치거나, 그림판밖으로나가거나,검은칸 덮을때) false
bool set(vector<vector<int>>& board, int y, int x, int type, int delta);
//board의 모든 빈칸을 덮을 수 있는 방법의 수 반환
//board[i][j]=1 이미 덮인 칸 또는 검은칸
//board[i][j]=0 아직 덮이지 않은 칸
int cover(vector<vector<int>>& board);
int main() {
int testCase, H, W;
char ch;
cin >> testCase;
for (int i = 0; i < testCase; i++) {
cin >> H>> W;
vector<vector<int>> board;
for (int m = 0; m < H; m++) {
vector<int>tmp(W);
board.push_back(tmp);
}
for (int m = 0; m < H; m++) {
for (int n = 0; n < W; n++) {
cin >> ch;
if (ch == '#') board[m][n] = 1;
else if(ch == '.') board[m][n] = 0;
}
}
int ret = cover(board);
cout << ret<<endl;
}
}
bool set(vector<vector<int>>& board, int y, int x, int type, int delta) {
bool ok = true;
for (int i = 0; i < 3; ++i) {
const int ny = y + coverType[type][i][0];
const int nx = x + coverType[type][i][1];
if (ny < 0 || ny >= board.size() || nx < 0 || nx >= board[0].size()) {
ok = false;
}
else if ((board[ny][nx] += delta) > 1)
ok = false;
}
return ok;
}
int cover(vector<vector<int>>& board) {
//아직 채우지 못한 칸 중 가장 윗줄 왼쪽에 있는 칸 찾기
int y = -1, x = -1;
for (int i = 0; i < board.size(); ++i) {
for (int j = 0; j < board[i].size(); ++j) {
if (board[i][j] == 0) {
y = i;
x = j;
break;
}
}
if (y != -1) break;
}
//base case: 모든 칸을 채웠으면 1을 반환
if (y == -1) return 1;
int ret = 0;
for (int type = 0; type < 4; type++) {
//만약 board[y][x]를 type형태로 덮을 수 있으면 재귀호출
if (set(board, y, x, type, 1))
ret += cover(board);
//덮었던 블록을 치운다.
set(board, y, x, type, -1);
}
return ret;
}
728x90
'아카이브' 카테고리의 다른 글
[2020 정보처리기사 필기] 2.4.51 테스트 기법에 따른 애플리케이션 테스트 (0) | 2020.04.01 |
---|---|
[알고리즘] 여행하는 외판원 문제(TSP) (0) | 2020.04.01 |
[2020 정보처리기사 필기] 2.4.50 애플리케이션 테스트 분류 (0) | 2020.04.01 |
[2020 정보처리기사 필기] 2.3.48 빌드 자동화 도구 (0) | 2020.04.01 |
[2020 정보처리기사 필기] 2.3.47 소프트웨어 버전 관리 도구 (0) | 2020.04.01 |
Comments