문제주소 :programmers.co.kr/learn/courses/30/lessons/77485#
코딩테스트 연습 - 행렬 테두리 회전하기
6 6 [[2,2,5,4],[3,3,6,6],[5,1,6,3]] [8, 10, 25] 3 3 [[1,1,2,2],[1,2,2,3],[2,1,3,2],[2,2,3,3]] [1, 1, 5, 3]
programmers.co.kr
<문제 설명>
문제 설명
rows x columns 크기인 행렬이 있습니다. 행렬에는 1부터 rows x columns까지의 숫자가 한 줄씩 순서대로 적혀있습니다. 이 행렬에서 직사각형 모양의 범위를 여러 번 선택해, 테두리 부분에 있는 숫자들을 시계방향으로 회전시키려 합니다. 각 회전은 (x1, y1, x2, y2)인 정수 4개로 표현하며, 그 의미는 다음과 같습니다.
- x1 행 y1 열부터 x2 행 y2 열까지의 영역에 해당하는 직사각형에서 테두리에 있는 숫자들을 한 칸씩 시계방향으로 회전합니다.
다음은 6 x 6 크기 행렬의 예시입니다.
![](https://blog.kakaocdn.net/dn/U90sf/btq3ucdlOyW/4FbKrGhKhjGljco8njEDqk/img.png)
이 행렬에 (2, 2, 5, 4) 회전을 적용하면, 아래 그림과 같이 2행 2열부터 5행 4열까지 영역의 테두리가 시계방향으로 회전합니다. 이때, 중앙의 15와 21이 있는 영역은 회전하지 않는 것을 주의하세요.
![](https://blog.kakaocdn.net/dn/bQxhZ3/btq3q6reOp6/3EmzA7ttkHGfvHa7Q32O51/img.png)
행렬의 세로 길이(행 개수) rows, 가로 길이(열 개수) columns, 그리고 회전들의 목록 queries가 주어질 때, 각 회전들을 배열에 적용한 뒤, 그 회전에 의해 위치가 바뀐 숫자들 중 가장 작은 숫자들을 순서대로 배열에 담아 return 하도록 solution 함수를 완성해주세요.
제한사항
- rows는 2 이상 100 이하인 자연수입니다.
- columns는 2 이상 100 이하인 자연수입니다.
- 처음에 행렬에는 가로 방향으로 숫자가 1부터 하나씩 증가하면서 적혀있습니다.
- 즉, 아무 회전도 하지 않았을 때, i 행 j 열에 있는 숫자는 ((i-1) x columns + j)입니다.
- queries의 행의 개수(회전의 개수)는 1 이상 10,000 이하입니다.
- queries의 각 행은 4개의 정수 [x1, y1, x2, y2]입니다.
- x1 행 y1 열부터 x2 행 y2 열까지 영역의 테두리를 시계방향으로 회전한다는 뜻입니다.
- 1 ≤ x1 < x2 ≤ rows, 1 ≤ y1 < y2 ≤ columns입니다.
- 모든 회전은 순서대로 이루어집니다.
- 예를 들어, 두 번째 회전에 대한 답은 첫 번째 회전을 실행한 다음, 그 상태에서 두 번째 회전을 실행했을 때 이동한 숫자 중 최솟값을 구하면 됩니다.
입출력 예시
rowscolumnsqueriesresult6 | 6 | [[2,2,5,4],[3,3,6,6],[5,1,6,3]] | [8, 10, 25] |
3 | 3 | [[1,1,2,2],[1,2,2,3],[2,1,3,2],[2,2,3,3]] | [1, 1, 5, 3] |
100 | 97 | [[1,1,100,97]] | [1] |
입출력 예 설명
입출력 예 #1
- 회전을 수행하는 과정을 그림으로 표현하면 다음과 같습니다.
입출력 예 #2
- 회전을 수행하는 과정을 그림으로 표현하면 다음과 같습니다.
입출력 예 #3
- 이 예시에서는 행렬의 테두리에 위치한 모든 칸들이 움직입니다. 따라서, 행렬의 테두리에 있는 수 중 가장 작은 숫자인 1이 바로 답이 됩니다.
<풀이법>
▒ 한줄 개념: 구현 ▒
구현 문제이다. 풀이방식은 아래와 같다. 코드를 한번 보면 이해가 쉽다.
1. rows * columns 행렬 생성 및 초기화 (1부터 채움).
2. query값에 따른 회전 함수 구현: 이때 최소값을 찾아 answer에 삽입.
회전 함수는 다음과 같은 순서로 구현하였다. 하지만 어떤방식으로든 구현만 하면 되므로, 자신이 생각하기에 가장 좋은 방식을 사용하면 될 것 같다.
<주의사항>
1. 처음에 행렬 값을 초기화 할 때 올바른 값을 넣는게 중요하다. 여기서 실수하여 시간을 조금 쏟았다.
2. 회전시 가장 작은 숫자들을 뽑아서 정답배열에 넣어주는것도 명심해야 한다.
<코드(Java)>
import java.util.*;
class Solution {
int[][] matrix;
public int[] solution(int rows, int columns, int[][] queries) {
this.matrix = new int[rows][columns]; // 행렬 생성
int[] answer = new int[queries.length]; // 정답 배열
for(int i = 0; i < rows; i++){ // 행렬 초기화
for(int j = 0; j < columns; j++){
matrix[i][j] = i*columns + j + 1;
}
}
for(int i = 0; i < queries.length; i++){ // 회전하고 최솟값 answer에 저장
answer[i] = rotate(queries[i]);
}
return answer;
}
public int rotate(int[] query){
int r1 = query[0]-1;
int c1 = query[1]-1;
int r2 = query[2]-1;
int c2 = query[3]-1;
int temp = this.matrix[r1][c1]; // 시작위치 값 임시저장
int min = temp; // min값 초기화
for(int i = r1; i < r2; i++){ // 회전의 1번
this.matrix[i][c1] = this.matrix[i+1][c1];
if(min > this.matrix[i][c1]) min = this.matrix[i][c1];
}
for(int i = c1; i < c2; i++){ // 회전의 2번
this.matrix[r2][i] = this.matrix[r2][i+1];
if(min > this.matrix[r2][i]) min = this.matrix[r2][i];
}
for(int i = r2; i > r1; i--){ // 회전의 3번
this.matrix[i][c2] = this.matrix[i-1][c2];
if(min > this.matrix[i][c2]) min = this.matrix[i][c2];
}
for(int i = c2; i > c1; i--){ // 회전의 4번
this.matrix[r1][i] = this.matrix[r1][i-1];
if(min > this.matrix[r1][i]) min = this.matrix[r1][i];
}
this.matrix[r1][c1+1] = temp; // 임시저장한 값 저장
return min; 최솟값 반환
}
}
더 많은 코드 보기(GitHub) : github.com/dwkim-97/CodingTest
'Programmers' 카테고리의 다른 글
[프로그래머스] 다단계 칫솔 판매 / Java (1) | 2021.04.27 |
---|---|
[프로그래머스] 로또의 최고 순위와 최저 순위 / Java (0) | 2021.04.27 |
[프로그래머스] 최적의 행렬 곱셈 / Java (0) | 2021.04.26 |
[프로그래머스] 모두 0으로 만들기 / Java (0) | 2021.04.22 |
[프로그래머스] 괄호 회전하기 / Java (0) | 2021.04.21 |