Skip to content

Commit 07c26ef

Browse files
committed
[level 3] Title: 고고학 최고의 발견, Time: 247.48 ms, Memory: 101 MB -BaekjoonHub
1 parent 9082f43 commit 07c26ef

2 files changed

Lines changed: 155 additions & 0 deletions

File tree

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
# [level 3] 고고학 최고의 발견 - 131702
2+
3+
[문제 링크](https://school.programmers.co.kr/learn/courses/30/lessons/131702#qna)
4+
5+
### 성능 요약
6+
7+
메모리: 101 MB, 시간: 247.48 ms
8+
9+
### 구분
10+
11+
코딩테스트 연습 > 연습문제
12+
13+
### 채점결과
14+
15+
정확성: 100.0<br/>합계: 100.0 / 100.0
16+
17+
### 제출 일자
18+
19+
2025년 02월 11일 15:57:59
20+
21+
### 문제 설명
22+
23+
<p>고고학자인 혜선은 오래전부터 성궤의 행방을 추적해왔습니다. 그동안 그의 연구는 주류 학자들로부터 인정받지 못했었지만, 혜선이는 포기하지 않고 조사를 계속했고 마침내 성궤의 행방을 알아내었습니다.</p>
24+
25+
<p>그러나 오래전 누군가로부터 봉인된 성궤는 특별한 잠금장치에 의해 보호되고 있었습니다. 잠금장치는 일종의 퍼즐과 연결되어 퍼즐을 해결하면 열리는 것으로 보입니다.</p>
26+
27+
<p>퍼즐은 시계들이 행렬을 이루는 구조물인데 하나의 시계에 시곗바늘은 하나씩만 있습니다. 각 시곗바늘은 시계방향으로만 돌릴 수 있고 한 번의 조작으로 90도씩 돌릴 수 있습니다. 시계들은 기계장치에 의해 연결되어 있어 어떤 시계의 시곗바늘을 돌리면 그 시계의 상하좌우로 인접한 시계들의 시곗바늘도 함께 돌아갑니다. 행렬의 모서리에 위치한 시계의 시곗바늘을 돌리는 경우에는 인접한 세 시계의 시곗바늘들이 함께 돌아가며, 꼭짓점에 위치한 시계의 시곗바늘을 돌리는 경우에는 인접한 두 시계의 시곗바늘들이 함께 돌아갑니다.</p>
28+
29+
<p>각 시계는 12시, 3시, 6시, 9시 방향 중의 한 방향을 가리키고 있습니다. 각 시계의 시곗바늘을 적절히 조작하여 모든 시곗바늘이 12시 방향을 가리키면 퍼즐이 해결되어 성궤를 봉인하고 있는 잠금장치가 열릴 것입니다.</p>
30+
31+
<p>노후화된 퍼즐 기계장치가 걱정되었던 혜선은 가능한 최소한의 조작으로 퍼즐을 해결하려고 합니다. 시곗바늘들의 행렬 <code>clockHands</code>가 매개변수로 주어질 때, 퍼즐을 해결하기 위한 최소한의 조작 횟수를 return 하도록 solution 함수를 완성해주세요.</p>
32+
33+
<hr>
34+
35+
<h5>제한사항</h5>
36+
37+
<ul>
38+
<li>2 ≤ <code>clockHands</code>의 길이 ≤ 8</li>
39+
<li><code>clockHands</code>는 2차원 배열이며 행과 열의 크기가 동일합니다.</li>
40+
<li>0 ≤ <code>clockHands</code>의 원소 ≤ 3</li>
41+
<li><code>clockHands[i]</code>의 원소들은 시곗바늘의 방향을 나타내며 0은 12시 방향, 1은 3시 방향, 2는 6시 방향, 3은 9시 방향을 나타냅니다.</li>
42+
<li>해결 가능한 퍼즐만 주어집니다.</li>
43+
</ul>
44+
45+
<hr>
46+
47+
<h5>입출력 예</h5>
48+
<table class="table">
49+
<thead><tr>
50+
<th>clockHands</th>
51+
<th>result</th>
52+
</tr>
53+
</thead>
54+
<tbody><tr>
55+
<td>[[0,3,3,0],[3,2,2,3],[0,3,2,0],[0,3,3,3]]</td>
56+
<td>3</td>
57+
</tr>
58+
</tbody>
59+
</table>
60+
<hr>
61+
62+
<h5>입출력 예 설명</h5>
63+
64+
<p>입출력 예 #1<br>
65+
2행 2열의 시곗바늘, 2행 3열의 시곗바늘, 4행 3열의 시곗바늘을 각각 한 번씩 돌리면 최소 조작 횟수로 퍼즐을 해결할 수 있습니다.<br>
66+
<img src="https://grepp-programmers.s3.ap-northeast-2.amazonaws.com/files/production/e5622019-c4b1-4306-b72d-3efe1d3c62d3/%EA%B7%B8%EB%A6%BC.png" title="" alt="그림.png"></p>
67+
68+
69+
> 출처: 프로그래머스 코딩 테스트 연습, https://school.programmers.co.kr/learn/challenges
Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
import java.util.*;
2+
3+
class Solution {
4+
int[] dx = {0, -1, 0, 1, 0};
5+
int[] dy = {0, 0, 1, 0, -1};
6+
7+
int n, ans;
8+
int[][] origin;
9+
public int solution(int[][] clockHands) {
10+
int answer = 0;
11+
preSetting(clockHands);
12+
dfs(new int[n], 0);
13+
14+
return ans;
15+
}
16+
17+
int[][] clonePuzzle(int[] rotation){
18+
int[][] clonetest = new int[n + 1][n];
19+
Arrays.setAll(clonetest[0], (col) -> rotation[col]);
20+
21+
for(int i = 0; i < n; i++){
22+
int row = i;
23+
Arrays.setAll(clonetest[i + 1], (col) -> origin[row][col]);
24+
}
25+
26+
return clonetest;
27+
}
28+
29+
30+
// rotation: 첫번째 행의 회전관련 데이터 저장 배열:
31+
// 만약 2라면 2 -> 0으로 바꿀 수 있도록 rotationPuzzle함수에서 처리할 예정
32+
void dfs(int[] rotation, int depth){
33+
34+
if(depth == n){ // 회전 진행
35+
int[][] clone = clonePuzzle(rotation);
36+
ans = Math.min(rotationPuzzle(clone), ans);
37+
return;
38+
}
39+
40+
for(int d = 0; d < 4; d++) {
41+
rotation[depth] = d;
42+
dfs(rotation, depth + 1);
43+
}
44+
}
45+
46+
47+
48+
int rotationPuzzle(int[][] puzzle){
49+
int move = 0;
50+
int nx, ny, degree;
51+
52+
for(int i = 1; i < n + 1; i++){
53+
for(int j = 0; j < n; j++){
54+
degree = (4 - puzzle[i - 1][j]) % 4;
55+
move += degree;
56+
57+
if(degree == 0) continue;
58+
for(int d = 0; d < 5; d++){
59+
nx = i + dx[d];
60+
ny = j + dy[d];
61+
62+
if(nx < 0 || n < nx || ny < 0 || n <= ny) continue;
63+
puzzle[nx][ny] = (puzzle[nx][ny] + degree) % 4;
64+
}
65+
}
66+
}
67+
if(!isZero(puzzle)) return Integer.MAX_VALUE;
68+
return move;
69+
}
70+
71+
boolean isZero(int[][] puzzle){
72+
for(int i = 1; i < n + 1; i++){
73+
for(int j = 0; j < n; j++){
74+
if(puzzle[i][j] != 0) return false;
75+
}
76+
}
77+
78+
return true;
79+
}
80+
81+
void preSetting(int[][] clockHands){
82+
origin = clockHands;
83+
n = clockHands.length;
84+
ans = Integer.MAX_VALUE;
85+
}
86+
}

0 commit comments

Comments
 (0)