salsa source

[BOJ] 14500 : 테트로미노 (DFS 만으로 풀기/C C++) 본문

STUDY/알고리즘

[BOJ] 14500 : 테트로미노 (DFS 만으로 풀기/C C++)

dayofday 2018. 4. 6. 04:08


BOJ 문제 링크





문제 풀이 POINT!


1. 테트로미노의 블록은 모두 4개로 구성되어있다.

2. 회전이나 대칭이 가능하다.



4개로만 구성되어있기 때문에 모든 경우의 수를 배열에 담아 확인하는 방법도 있겠지만(실제로 BOJ 소스에 많다!)

회전이나 대칭이 가능하기 때문에 만들어야 하는 배열의 경우의 수가 너무 많아 귀찮아서 탐색으로 풀이를 하였다.


회전이나 대칭이 가능하다 라는 조건이 문제를 더 까다롭게 만드는 것 처럼 보이지만 탐색으로 풀이를 한다면 더욱 쉽게 만드는 조건이다.



BFS와 DFS 모두 풀이가 가능하겠지만 나는 DFS로 문제를 풀었다.

DFS로 문제를 푼다면 입력받은 배열에서 시작점을 정하여 각 시작점에서 4칸을 탐색하여 블록을 만들어볼 수 있겠다.

여기까지는 많은 사람들이 쉽게 생각한다. 하지만 예외가 생긴다.

바로 'ㅗ' 'ㅏ' 'ㅓ' 'ㅜ' 모양이다.



1. 출발지점에서 DFS시작(한 칸)                                              2. DFS 두 칸 탐색

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 


3. DFS 세 칸 탐색                                                                       4. 여기서 노란색은 어떻게 탐색해야 할까?!

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 


그냥 DFS로 4칸을 탐색한다면, 위와 같이 'ㅗ' 모양은 가운데에서 분기가 생기기 때문에 탐색할 수가 없다. 따라서 아이디어가 필요하다.


내가 생각한 아이디어는 갈라지는 분기에서 DFS를 한 번 더 하는 것이다.


노란 칸은 3에서는 탐색 불가능하지만 2에서 가능하다. ㅗ 모양을 만들기 위해서는 2에서 (오른쪽, 위), (오른쪽, 아래), (위, 아래) 조합의 칸을 탐색해야하고, 3과 같이 한 칸만 탐색한다면 만들 수 없다.
따라서 2에서 두 번 탐색을 하면 된다.

DFS 함수 안에서 현재 위치 (x, y) 에서 갈 수 있는 다음 위치 (xx, yy)를 탐색한다.
이 때 DFS의 깊이가 2라면 (x, y)에서 갈 수 있는 또 다른 다음 위치 (xxx, yyy)를 탐색하고 DFS 재귀를 타면 되는 것이다.
깊이가 2일 때 두 칸을 탐색했으니, 다음 재귀의 깊이는 3이 아닌 4가 되고 return을 해주면 된다.











'STUDY > 알고리즘' 카테고리의 다른 글

[BOJ] 1021번 : 회전하는 큐 (C/C++)  (0) 2018.04.03
Comments