행렬 테두리 회전하기
rows x columns 크기인 행렬이 있습니다. 행렬에는 1부터 rows x columns까지의 숫자가 한 줄씩 순서대로 적혀있습니다. 이 행렬에서 직사각형 모양의 범위를 여러 번 선택해, 테두리 부분에 있는 숫자들을 시계방향으로 회전시키려 합니다. 각 회전은 (x1, y1, x2, y2)인 정수 4개로 표현하며, 그 의미는 다음과 같습니다.
- x1 행 y1 열부터 x2 행 y2 열까지의 영역에 해당하는 직사각형에서 테두리에 있는 숫자들을 한 칸씩 시계방향으로 회전합니다.
다음은 6 x 6 크기 행렬의 예시입니다.
![](https://blog.kakaocdn.net/dn/bOFPy3/btsGQXOJIqP/tk9rerRX2ocbwnyzQPrYr1/img.png)
이 행렬에 (2, 2, 5, 4) 회전을 적용하면, 아래 그림과 같이 2행 2열부터 5행 4열까지 영역의 테두리가 시계방향으로 회전합니다. 이때, 중앙의 15와 21이 있는 영역은 회전하지 않는 것을 주의하세요.
![](https://blog.kakaocdn.net/dn/1eAf7/btsGQ0dBV28/DRfqo1XCGyiEVBfbyDVT7k/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입니다.
- 모든 회전은 순서대로 이루어집니다.
- 예를 들어, 두 번째 회전에 대한 답은 첫 번째 회전을 실행한 다음, 그 상태에서 두 번째 회전을 실행했을 때 이동한 숫자 중 최솟값을 구하면 됩니다.
입출력 예시
rows | columns | queries | result |
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] |
100 | 97 | [[1,1,100,97]] | [1] |
내가 푼 풀이
- 회전을 구현하여 해당 범위를 교체하고, 최솟값을 저장한다.
- 따로 다른 알고리즘 없이 회전하는 동작을 구현하면 된다.
import Foundation
func solution(_ rows:Int, _ columns:Int, _ queries:[[Int]]) -> [Int] {
var board = Array(repeating:Array(repeating: 0, count: columns+1), count: rows+1)
var answer = [Int]()
// 입력
for i in 1...rows {
for j in 1...columns {
board[i][j] = ((i-1) * columns + j)
}
}
// 쿼리 돌리기
var b = board
for query in queries {
var a = moveNums(query, b)
var minNum = a.removeLast()
answer += minNum
b = a
}
return answer
}
func moveNums(_ query: [Int],_ arr: [[Int]]) -> [[Int]] {
var dx = [1, 0, -1, 0]
var dy = [0, 1, 0, -1]
var a = arr
var mx = query[1]
var my = query[0]
var rc = query[3] - query[1]
var cc = query[2] - query[0]
var previous = a[my][mx]
var minNum = a[my][mx]
// 회전하며, 저장된 값과 그 다음의 값을 비교해 최솟값 갱신
for i in 0..<4 {
if i == 0 || i == 2 {
for j in 0..<rc {
mx += dx[i]
my += dy[i]
minNum = min(minNum, a[my][mx])
var tmp = a[my][mx]
a[my][mx] = previous
previous = tmp
}
} else {
for j in 0..<cc {
mx += dx[i]
my += dy[i]
minNum = min(minNum, a[my][mx])
var tmp = a[my][mx]
a[my][mx] = previous
previous = tmp
}
}
}
a.append([minNum])
return a
}
'코딩테스트 > 프로그래머스' 카테고리의 다른 글
[프로그래머스] 미로 탈출 Swift (1) | 2024.04.23 |
---|---|
[프로그래머스] 수식 최대화 Swift (0) | 2024.04.22 |
[프로그래머스] 괄호 변환 Swift (0) | 2024.04.22 |
[프로그래머스] 무인도 여행 Swift (0) | 2024.04.18 |
[프로그래머스] [3차] 방금그곡 Swift (1) | 2024.04.18 |