Skip to content

Commit e822fc4

Browse files
committed
[level 2] Title: 행렬 테두리 회전하기, Time: 61.44 ms, Memory: 116 MB -BaekjoonHub
1 parent d17b544 commit e822fc4

File tree

2 files changed

+242
-0
lines changed

2 files changed

+242
-0
lines changed
Lines changed: 118 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,118 @@
1+
# [level 2] 행렬 테두리 회전하기 - 77485
2+
3+
[문제 링크](https://school.programmers.co.kr/learn/courses/30/lessons/77485)
4+
5+
### 성능 요약
6+
7+
메모리: 116 MB, 시간: 61.44 ms
8+
9+
### 구분
10+
11+
코딩테스트 연습 > 2021 Dev-Matching: 웹 백엔드 개발자(상반기)
12+
13+
### 채점결과
14+
15+
정확성: 100.0<br/>합계: 100.0 / 100.0
16+
17+
### 제출 일자
18+
19+
2025년 08월 27일 10:32:35
20+
21+
### 문제 설명
22+
23+
<p>rows x columns 크기인 행렬이 있습니다. 행렬에는 1부터 rows x columns까지의 숫자가 한 줄씩 순서대로 적혀있습니다. 이 행렬에서 직사각형 모양의 범위를 여러 번 선택해, 테두리 부분에 있는 숫자들을 시계방향으로 회전시키려 합니다. 각 회전은 (x1, y1, x2, y2)인 정수 4개로 표현하며, 그 의미는 다음과 같습니다.</p>
24+
25+
<ul>
26+
<li>x1 행 y1 열부터 x2 행 y2 열까지의 영역에 해당하는 직사각형에서 테두리에 있는 숫자들을 한 칸씩 시계방향으로 회전합니다.</li>
27+
</ul>
28+
29+
<p>다음은 6 x 6 크기 행렬의 예시입니다.</p>
30+
31+
<p><img src="https://grepp-programmers.s3.ap-northeast-2.amazonaws.com/files/ybm/4c3c0fab-11f4-43b6-b290-6f4017e9379f/grid_example.png" title="" alt="grid_example.png"></p>
32+
33+
<p>이 행렬에 (2, 2, 5, 4) 회전을 적용하면, 아래 그림과 같이 2행 2열부터 5행 4열까지 영역의 테두리가 시계방향으로 회전합니다. 이때, 중앙의 15와 21이 있는 영역은 회전하지 않는 것을 주의하세요.</p>
34+
35+
<p><img src="https://grepp-programmers.s3.ap-northeast-2.amazonaws.com/files/ybm/962df137-5c71-4091-ad9f-8e322910c1ab/rotation_example.png" title="" alt="rotation_example.png"></p>
36+
37+
<p>행렬의 세로 길이(행 개수) rows, 가로 길이(열 개수) columns, 그리고 회전들의 목록 queries가 주어질 때, 각 회전들을 배열에 적용한 뒤, 그 회전에 의해 위치가 바뀐 숫자들 중 <u><strong>가장 작은 숫자들을 순서대로 배열에 담아</strong></u> return 하도록 solution 함수를 완성해주세요.</p>
38+
39+
<hr>
40+
41+
<h5>제한사항</h5>
42+
43+
<ul>
44+
<li>rows는 2 이상 100 이하인 자연수입니다.</li>
45+
<li>columns는 2 이상 100 이하인 자연수입니다.</li>
46+
<li>처음에 행렬에는 가로 방향으로 숫자가 1부터 하나씩 증가하면서 적혀있습니다.
47+
48+
<ul>
49+
<li>즉, 아무 회전도 하지 않았을 때, i 행 j 열에 있는 숫자는 ((i-1) x columns + j)입니다.</li>
50+
</ul></li>
51+
<li>queries의 행의 개수(회전의 개수)는 1 이상 10,000 이하입니다.</li>
52+
<li>queries의 각 행은 4개의 정수 [x1, y1, x2, y2]입니다.
53+
54+
<ul>
55+
<li>x1 행 y1 열부터 x2 행 y2 열까지 영역의 테두리를 시계방향으로 회전한다는 뜻입니다.</li>
56+
<li>1 ≤ x1 &lt; x2 ≤ rows, 1 ≤ y1 &lt; y2 ≤ columns입니다.</li>
57+
<li>모든 회전은 순서대로 이루어집니다.</li>
58+
<li>예를 들어, 두 번째 회전에 대한 답은 첫 번째 회전을 실행한 다음, 그 상태에서 두 번째 회전을 실행했을 때 이동한 숫자 중 최솟값을 구하면 됩니다.</li>
59+
</ul></li>
60+
</ul>
61+
62+
<hr>
63+
64+
<h5>입출력 예시</h5>
65+
<table class="table">
66+
<thead><tr>
67+
<th>rows</th>
68+
<th>columns</th>
69+
<th>queries</th>
70+
<th>result</th>
71+
</tr>
72+
</thead>
73+
<tbody><tr>
74+
<td><code>6</code></td>
75+
<td><code>6</code></td>
76+
<td><code>[[2,2,5,4],[3,3,6,6],[5,1,6,3]]</code></td>
77+
<td><code>[8, 10, 25]</code></td>
78+
</tr>
79+
<tr>
80+
<td><code>3</code></td>
81+
<td><code>3</code></td>
82+
<td><code>[[1,1,2,2],[1,2,2,3],[2,1,3,2],[2,2,3,3]]</code></td>
83+
<td><code>[1, 1, 5, 3]</code></td>
84+
</tr>
85+
<tr>
86+
<td><code>100</code></td>
87+
<td><code>97</code></td>
88+
<td><code>[[1,1,100,97]]</code></td>
89+
<td><code>[1]</code></td>
90+
</tr>
91+
</tbody>
92+
</table>
93+
<hr>
94+
95+
<h5>입출력 예 설명</h5>
96+
97+
<p>입출력 예 #1</p>
98+
99+
<ul>
100+
<li>회전을 수행하는 과정을 그림으로 표현하면 다음과 같습니다.</li>
101+
<li><img src="https://grepp-programmers.s3.ap-northeast-2.amazonaws.com/files/ybm/8c8cdd84-d0ec-4b9d-bdf7-f100d0098c5e/example1.png" title="" alt="example1.png"></li>
102+
</ul>
103+
104+
<p>입출력 예 #2</p>
105+
106+
<ul>
107+
<li>회전을 수행하는 과정을 그림으로 표현하면 다음과 같습니다.</li>
108+
<li><img src="https://grepp-programmers.s3.ap-northeast-2.amazonaws.com/files/ybm/e3fce2bf-9da9-41e4-926a-5d19b4f31188/example2.png" title="" alt="example2.png"></li>
109+
</ul>
110+
111+
<p>입출력 예 #3</p>
112+
113+
<ul>
114+
<li>이 예시에서는 행렬의 테두리에 위치한 모든 칸들이 움직입니다. 따라서, 행렬의 테두리에 있는 수 중 가장 작은 숫자인 1이 바로 답이 됩니다.</li>
115+
</ul>
116+
117+
118+
> 출처: 프로그래머스 코딩 테스트 연습, https://school.programmers.co.kr/learn/challenges
Lines changed: 124 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,124 @@
1+
import java.util.*;
2+
class Solution {
3+
// 시계방향 순서: ➡️⬇️⬅️⬆️
4+
int[] dx = {0,1,0,-1};
5+
int[] dy = {1,0,-1,0};
6+
int[][] board;
7+
int minNumber = Integer.MAX_VALUE;
8+
9+
public int[] solution(int rows, int columns, int[][] queries) {
10+
board = new int[rows+1][columns+1];
11+
int number = 1;
12+
int[] answer = new int[queries.length];
13+
14+
for(int i=1;i<=rows;i++){
15+
for(int j = 1;j<=columns;j++){
16+
board[i][j] = number++;
17+
}
18+
}
19+
20+
int idx =0;
21+
for(int[] query : queries){
22+
int startX = query[0];
23+
int startY = query[1];
24+
int endX = query[2];
25+
int endY = query[3];
26+
27+
// 총 움직일 거리
28+
int dRow = endX - startX;
29+
int dCol = endY - startY;
30+
31+
// 이동
32+
move(startX,startY,endX,endY,dRow,dCol);
33+
answer[idx++] = minNumber;
34+
}
35+
36+
return answer;
37+
}
38+
39+
void move(int startX,int startY,int endX,int endY,int dRow,int dCol){
40+
// [x좌표,y좌표,값]
41+
Queue<int[]> queue = new LinkedList<>();
42+
queue.offer(new int[]{startX,startY,board[startX][startY]});
43+
44+
int[] current = new int[3];
45+
int currentX;
46+
int currentY;
47+
int currentNumber;
48+
int newNumber;
49+
int nextX;
50+
int nextY;
51+
minNumber = board[startX][startY];
52+
// ➡️
53+
for(int i = 0; i< dCol; i++){
54+
current = queue.poll(); // 기존 값 추출
55+
currentX = current[0]; // x좌표
56+
currentY = current[1]; // y좌표
57+
currentNumber = current[2]; // 값
58+
59+
nextX = currentX + dx[0];
60+
nextY = currentY + dy[0];
61+
newNumber = board[nextX][nextY];
62+
if(newNumber < minNumber) minNumber = newNumber;
63+
64+
// 새로운 값 큐에 주입
65+
queue.offer(new int[]{nextX,nextY,newNumber});
66+
// 기존 값 이동 한 칸에 주입
67+
board[nextX][nextY] = currentNumber;
68+
}
69+
// ⬇️
70+
for(int i = 0; i< dRow; i++){
71+
current = queue.poll(); // 기존 값 추출
72+
currentX = current[0]; // x좌표
73+
currentY = current[1]; // y좌표
74+
currentNumber = current[2]; // 값
75+
76+
nextX = currentX + dx[1];
77+
nextY = currentY + dy[1];
78+
newNumber = board[nextX][nextY];
79+
if(newNumber < minNumber) minNumber = newNumber;
80+
81+
// 새로운 값 큐에 주입
82+
queue.offer(new int[]{nextX,nextY,newNumber});
83+
// 기존 값 이동 한 칸에 주입
84+
board[nextX][nextY] = currentNumber;
85+
86+
}
87+
// ⬅️
88+
for(int i = 0; i< dCol; i++){
89+
current = queue.poll(); // 기존 값 추출
90+
currentX = current[0]; // x좌표
91+
currentY = current[1]; // y좌표
92+
currentNumber = current[2]; // 값
93+
94+
nextX = currentX + dx[2];
95+
nextY = currentY + dy[2];
96+
newNumber = board[nextX][nextY];
97+
if(newNumber < minNumber) minNumber = newNumber;
98+
99+
// 새로운 값 큐에 주입
100+
queue.offer(new int[]{nextX,nextY,newNumber});
101+
// 기존 값 이동 한 칸에 주입
102+
board[nextX][nextY] = currentNumber;
103+
}
104+
// ⬆️
105+
for(int i = 0; i< dRow -1; i++){
106+
current = queue.poll(); // 기존 값 추출
107+
currentX = current[0]; // x좌표
108+
currentY = current[1]; // y좌표
109+
currentNumber = current[2]; // 값
110+
111+
nextX = currentX + dx[3];
112+
nextY = currentY + dy[3];
113+
newNumber = board[nextX][nextY];
114+
if(newNumber < minNumber) minNumber = newNumber;
115+
116+
// 새로운 값 큐에 주입
117+
queue.offer(new int[]{nextX,nextY,newNumber});
118+
// 기존 값 이동 한 칸에 주입
119+
board[nextX][nextY] = currentNumber;
120+
}
121+
// 시작 위치
122+
board[startX][startY] = queue.poll()[2];
123+
}
124+
}

0 commit comments

Comments
 (0)