본문 바로가기
Problem Solving/BOJ

백준 1022번 소용돌이 예쁘게 출력하기 - 스위프트(Swift) 풀이

by 어멘드 2022. 2. 9.
반응형

 

1. (r1, c1)부터 (r2, c2)까지 직접 채운다.
2. 가장 길이가 긴 숫자의 길이를 구한다.
3. 포맷에 맞춰 출력한다.

 

1. (r1, c1)부터 (r2, c2)까지 직접 채운다.

 단순 구현 문제이다. r, c 범위가 절댓값 5000까지인데, (-5000, -5000)부터 (5000, 5000)까지 전부 구해도 총 연산 횟수 10^8로 시간 초과가 나지 않는다. 하지만 10^8개의 Int를 선언하면 메모리 초과가 난다. 문제에서는 다음과 같은 조건을 두고 있다.

  • 0 ≤ r2 - r1 ≤ 49
  • 0 ≤ c2 - c1 ≤ 4

 따라서 실제 2차원 배열은 정답이 될 50*5 사이즈로만 선언해둔다. 그리고 소용돌이를 채울 때, 50*5 범위에 들어가는 것들만 정답 배열에 기록하고 범위 밖인 것은 그냥 스킵하면 된다. 소용돌이 채우는 구현은 인덱스 계산만 잘한다면 구현할 수 있다. 아래 코드는 1부터 시작해 한 겹씩 채워나가는 코드이다.

 

2. 가장 길이가 긴 숫자의 길이를 구한다.

 출력 조건이 굉장히 까다로워서 가장 길이가 긴 숫자의 길이에 맞춰서 출력해야한다. 가장 길이가 긴 숫자를 찾아서 그 길이를 구해준다. 정답 사이즈가 50*5밖에 되지 않기 때문에 완전 탐색으로 가장 큰 수를 찾아서 문자열로 변환한 뒤, 그 문자열의 길이로 구하는 방법을 사용했다.

 

3. 포맷에 맞춰 출력한다.

 String(format:)을 사용하였다. format을 "%3d"로 주면 총길이 3이 되도록 왼쪽에 공백을 주어 출력한다.

 

반응형

import Foundation

var r1 = 0, c1 = 0, r2 = 0, c2 = 0
var board = Array(repeating: Array(repeating: 0, count: 5), count: 50)

func fillBoard() {
    if (0..<50) ~= -r1 && (0..<5) ~= -c1 {
        board[-r1][-c1] = 1
    }
    
    var count = 2
    let maxSize = max(abs(r1), abs(c1), abs(r2), abs(c2))
    
    if maxSize == 0 { return }
    
    for size in 1...maxSize {
        for i in 0..<2*size {
            let directions = [
                (size-1-i - r1, size - c1),
                (-size - r1, size-1-i - c1),
                (-size+1+i - r1, -size - c1),
                (size - r1, -size+1+i - c1)
            ]
            
            for d in 0..<4 {
                let direction = directions[d]
                guard (0..<50) ~= direction.0 && (0..<5) ~= direction.1 else { continue }
                board[direction.0][direction.1] = count + 2 * d * size
            }
            
            count += 1
        }
        
        count += 6 * size
    }
}

func findMaxLength() -> Int {
    var maxValue = 0
    
    for i in r1...r2 {
        for j in c1...c2 {
            maxValue = max(board[i - r1][j - c1], maxValue)
        }
    }
    
    return String(maxValue).count
}

func solution() {
    let input = readLine()!.split(separator: " ").map{ Int(String($0))! }
    r1 = input[0]
    c1 = input[1]
    r2 = input[2]
    c2 = input[3]
    
    fillBoard()
    
    let maxLength = findMaxLength()
    
    var resultString = ""
    for i in r1...r2 {
        for j in c1...c2 {
            let formattedString = String(format: "%\(maxLength)d ", board[i - r1][j - c1])
            resultString.write(formattedString)
        }
        resultString.write("\n")
    }
    print(resultString)
}

solution()

 

반응형

댓글