티스토리 뷰

백준/백준 - 스위프트

17276번: 배열 돌리기

강철곰탱이 2023. 7. 1. 03:48
 

17276번: 배열 돌리기

각 테스트 케이스에 대해 회전 연산을 마친 후 배열의 상태를 출력한다. n줄에 걸쳐 각 줄에 n개의 정수를 공백으로 구분하여 출력한다. 

www.acmicpc.net

 

배열 돌리기 

크기가 n x n인 2차원 정수 배열 X가 있다. (n은 홀수)

X를 45° 의 배수만큼 시계방향 혹은 반시계방향으로 돌리려고 한다. X를 시계 방향으로 45° 돌리면 아래와 같은 연산이 동시에 X에 적용되어야 한다:

  • X의 주 대각선을 ((1,1), (2,2), …, (n, n)) 가운데 열 ((n+1)/2 번째 열)로 옮긴다.
  • X의 가운데 열을 X의 부 대각선으로 ((n, 1), (n-1, 2), …, (1, n)) 옮긴다. 
  • X의 부 대각선을 X의 가운데 행 ((n+1)/2번째 행)으로 옮긴다.
  • X의 가운데 행을 X의 주 대각선으로 옮긴다.
  • 위 네 가지 경우 모두 원소의 기존 순서는 유지 되어야 한다.
  • X의 다른 원소의 위치는 변하지 않는다.

반시계 방향으로 45° 돌리는 경우도 위와 비슷하게 정의된다.

입력

첫 줄에 테스트 케이스의 수 T가 주어진다 (1 ≤ T ≤ 10).

각 테스트 케이스에 대해: 첫 줄에 배열의 크기를 나타내는 n (1 ≤ n < 500, n은 홀수) 그리고 각도 d가 주어진다. d는 0 ≤ |d| ≤ 360 을 만족하며 |d| 는 45의 배수이다. d가 양수이면 시계방향으로 d° 돌려야 하고, 음수이면 반시계방향으로 |d|° 돌려야 한다. 다음 n줄에 걸쳐 각 줄에 n개의 정수가 공백으로 구분되어 주어진다 (X의 원소들을 나타낸다). 각 값은 1 이상 1,000,000 이하의 정수이다.

출력

각 테스트 케이스에 대해 회전 연산을 마친 후 배열의 상태를 출력한다. n줄에 걸쳐 각 줄에 n개의 정수를 공백으로 구분하여 출력한다. 


풀이

먼저 문제를 이해해보자.

문제에서 주어진 조건들을 살펴보면

1) 45도의 배수만큼 움직임.

2) 주 대각선, 가운데 열, 부 대각선, 가운데 행을 제외한 곳에 위치한 값은 바뀌지 x

3) 반시계 방향으로 돌리는 것도 시계 방향과 같은 조건

으로 정리할 수 있다.

 


설계

 

아래의 그림을 보면 1 -> 주대각선, 2 -> 가운데 열, 3 -> 부대각선, 4-> 가운데 행인 것을 알 수 있다. 

 일단 시계방향으로 돌아간다고 가정을 해보자.

시계방향으로 돌아간다면 1->2, 2->3, 3->4, 4->1로 움직이면서 계속 바뀌게 된다. 계속 이런식으로 움직인다면 우리는 규칙을 찾을 수 있다. 1의 위치에는 4의 값들, 2의 위치에는 1의 값들, 3의 위치에는 2의 값들, 4의 위치에는 3의 값들만 온다는 것을 확인할 수 있다. 

 

1의 좌표는 ((0,0), (1,1), …, (n-1, n-1))

2의 좌표는 ((n/2, 0),(n/2, 1), ..., (n/2, n-1))

3의 좌표는 ((n-0-1, 0)(n-1-1, 1), ..., (n-(n-1)-1, n-1)

4의 좌표는 ((0, n/2),(1, n/2), ..., (n-1, n/2)

서로의 좌표 값을 45의 배수만큼 바꿔주면 된다. 

 

=> 이렇게 서로 값을 갱신하기 전 배열의 값을 저장해놓고 바뀐 후의 값들로 바꿔주어야 한다. 바로 swap을 이용하는 것이다.

 

또 문제에서 주어진 반시계 방향은 어떻게 구하면 좋을까?

물론 시계방향 반대쪽으로 돌리면서 구할 수 있지만 너무 번거롭고 코드가 길어지니 (-)값인 반시계 방향에 +360도를 한 것이 시계방향으로 움직인 것과 같다는 점을 이용하여 쉽게 구해보자.  

 


코드 구현 

반시계와 시계 모두 한 방향으로만 구현하면 되니(시계방향) 함수는 rotateArr() 하나로 코드를 구현하였다.

 

1) 복사본 저장 배열과 복사본 아닌 값 저장할 배열 설정

 

2) 서로 해당하는 좌표 swap

 


전체코드

 

import Foundation

let t = Int(readLine()!)!
var arr: [[Int]] = []
var copyArr: [[Int]] = []//복사본 저장할 배열
var result: [String] = []

for _ in 0..<t{
    let input = readLine()!.split(separator: " ").map{Int(String($0))!}
    var (n, d) = (input[0], input[1])
    
    if(d<0){
        d += 360
    }
    d /= 45
    arr = []
    copyArr = []
    for _ in 0..<n {
        var arrValue = readLine()!.split(separator: " ").map { Int(String($0))! }
        arr.append(arrValue)
    }
    copyArr = arr
    
    for _ in 0..<d{
        rotateArr(n)
    }
    
    for value in arr{
        for v in value{
            result.append("\(v) ")
        }
        result.append("\n")
    }
}


func rotateArr(_ n: Int){
    let i = 0
    for i in 0..<n {
        copyArr[i][n/2] = arr[i][i];
        copyArr[i][i] = arr[n/2][i];
        copyArr[n/2][i] = arr[n-i-1][i];
        copyArr[n-i-1][i] = arr[n-i-1][n/2];
    }
    arr = copyArr
}

print(result.map{String($0)}.joined(separator: ""), terminator: "")//줄 바뀜 없이 출력위해 terminator

 

'백준 > 백준 - 스위프트' 카테고리의 다른 글

12865번: 평범한 배낭  (0) 2023.09.05
1912번: 연속합  (1) 2023.08.29
1074번: Z  (0) 2023.08.25
2630번: 색종이 만들기  (0) 2023.08.16
15787번: 기차가 어둠을 헤치고 은하수를  (1) 2023.07.27
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2025/05   »
1 2 3
4 5 6 7 8 9 10
11 12 13 14 15 16 17
18 19 20 21 22 23 24
25 26 27 28 29 30 31
글 보관함