프로그래머스
코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.
programmers.co.kr
class Solution {
public int[] solution(int rows, int columns, int[][] queries) {
int[] answer = new int[queries.length];
int[][] referenceMap = new int[rows + 1][columns + 1]; // 값 참조용 배열
int[][] map = new int[rows + 1][columns + 1]; // 회전시킨 값 저장할 배열
for (int r = 1; r <= rows; r++) {
for (int c = 1; c <= columns; c++) {
referenceMap[r][c] = ((r - 1) * columns + c);
map[r][c] = ((r - 1) * columns + c);
}
}
// ----- 입력 끝 -----
// 회전
for (int i = 0; i < queries.length; i++) {
int[] query = queries[i];
int x1 = query[0], y1 = query[1];
int x2 = query[2], y2 = query[3];
int min = Integer.MAX_VALUE;
// 위쪽 변
for (int j = y1 + 1; j <= y2; j++) {
map[x1][j] = referenceMap[x1][j - 1];
min = Math.min(min, map[x1][j]);
}
// 오른쪽 변
for (int j = x1 + 1; j <= x2; j++) {
map[j][y2] = referenceMap[j - 1][y2];
min = Math.min(min, map[j][y2]);
}
// 아래쪽 변
for (int j = y2 - 1; j >= y1; j--) {
map[x2][j] = referenceMap[x2][j + 1];
min = Math.min(min, map[x2][j]);
}
// 왼쪽 변
for (int j = x2 - 1; j >= x1; j--) {
map[j][y1] = referenceMap[j + 1][y1];
min = Math.min(min, map[j][y1]);
}
answer[i] = min;
// 다음 회전을 위해, referenceMap에 map을 복사
for (int r = 1; r <= rows; r++) {
for (int c = 1; c <= columns; c++) {
referenceMap[r][c] = map[r][c];
}
}
}
return answer;
}
}
1. 문제 요약
이 문제는 주어진 rows x columns 크기의 행렬에서 주어진 영역의 테두리를 시계방향으로 회전시키는 작업을 여러 번 수행한 후, 각 회전에서 이동한 숫자들 중 가장 작은 숫자를 구하는 문제입니다. 주어진 회전 명령을 차례로 수행하며 각 회전의 최소값을 기록하여 반환해야 합니다.
2. 핵심 아이디어
- 행렬 초기화:
- rows x columns 크기의 행렬을 초기화합니다. 각 위치 (i, j)에 대해 (i-1) * columns + j의 값을 가지도록 설정합니다.
- 회전 로직 구현:
- 각 회전 명령에 대해 테두리의 숫자들을 시계방향으로 한 칸씩 이동시키는 로직을 구현합니다. 이동 시 가장 작은 숫자를 기록합니다.
- 회전은 네 부분으로 나눠서 진행합니다:
- 위쪽 변: 오른쪽으로 이동
- 오른쪽 변: 아래로 이동
- 아래쪽 변: 왼쪽으로 이동
- 왼쪽 변: 위로 이동
- 이동 후 값 갱신:
- 각 회전이 끝난 후에는 결과를 저장할 map 배열에 값을 갱신하고, 다음 회전을 위해 referenceMap에 복사합니다.
- 최소값 저장:
- 각 회전마다 최소값을 계산하여 answer 배열에 저장합니다.
3. 출제 의도
- 배열 및 행렬 조작 능력:
- 2차원 배열(행렬)을 초기화하고 조작하는 능력을 요구합니다. 특히 특정 부분(테두리)을 선택하여 조작하는 능력을 테스트합니다.
- 구현력:
- 문제의 요구 사항을 정확히 이해하고, 이를 코드로 구현하는 능력을 측정합니다. 여기에는 입력과 출력을 처리하는 능력, 주어진 조건에 맞게 로직을 작성하는 능력이 포함됩니다.
- 시뮬레이션 및 시계 방향 회전 로직 구현:
- 주어진 명령에 따라 행렬의 특정 부분을 시계방향으로 회전시키는 시뮬레이션 능력을 테스트합니다. 이는 각 명령에 따라 정확한 위치의 값을 업데이트하고, 최소값을 추적하는 능력을 포함합니다.
- 최적화 및 효율성:
- 효율적으로 문제를 해결하기 위해 불필요한 작업(예: 중복된 배열 복사)을 피하고, 최소한의 연산으로 문제를 해결하는 능력을 측정합니다. 특히, 다수의 회전 명령이 주어졌을 때 효율적으로 처리할 수 있는지 테스트합니다.
- 기본적인 수학적 사고 및 문제 해결 능력:
- 문제를 해결하기 위해 기본적인 수학적 사고와 논리적 사고가 필요합니다. 예를 들어, 인덱스를 계산하고 업데이트하는 과정에서 정확한 수학적 사고가 요구됩니다.
- 경계 조건 및 예외 처리 능력:
- 배열의 경계를 넘어가지 않도록 주의하고, 다양한 입력 조건에 대해 올바르게 처리하는 능력을 테스트합니다.
이 문제를 해결하는 과정에서, 프로그래머는 복잡한 로직을 이해하고 구현할 수 있는 능력을 보여줄 수 있습니다. 이를 통해 면접관이나 문제 출제자는 프로그래머의 전반적인 알고리즘 문제 해결 능력, 구현 능력, 그리고 최적화 능력을 평가할 수 있습니다.
'알고리즘 문제 풀이' 카테고리의 다른 글
[prog 169199] 리코쳇 로봇 (0) | 2024.07.29 |
---|---|
[prog 87694] 아이템 줍기 (0) | 2024.07.29 |
[백준 1339] 단어 수학 (0) | 2024.07.21 |
[백준 2565] 전깃줄 (0) | 2024.07.21 |
[elice 알고리즘 코드 챌린지] Day 3 - 문자열 압축 해제 (0) | 2024.07.10 |