(Swift) 백준 1018 체스판 다시 칠하기

SteadySlower·2022년 5월 29일
0

Coding Test

목록 보기
50/305

1018번: 체스판 다시 칠하기

typealias Board = Array<Array<Character>>

let nums = readLine()!.split(separator: " ").map { Int(String($0))! }
let N = nums[0], M = nums[1]
var input = [Array<Character>]()

for _ in 0..<N {
    let line = readLine()!.map { $0 }
    input.append(line)
}

//💡 체스판은 BWBW로 반복되거나 WBWB로 반복되는 구조임
    // 따라서 BWBW로 반복되는 경우 다시 칠해야하는 칸과
    // WBWB로 반복되는 경우 다시 칠해야하는 칸을 비교해서
    // 더 작은 칸을 출력한다.
func countRepaint(board: Board) -> Int {
    var result1 = 0 //👉 WBWB 패턴
    var result2 = 0 //👉 BWBW 패턴
    for i in 0..<8 {
        for j in 0..<8 {
            if (i + j) % 2 == 0 { //👉 첫 칸을 기준으로 따지면 쉽다: [0][0]
                if board[i][j] == "B" { // 👉 첫칸이 B이면
                    result1 += 1 //👉 WBWB 패턴 다시 칠하기
                } else { // 👉 첫칸이 W이면
                    result2 += 1 //👉 BWBW 패턴 다시 칠하기
                }
            } else { //👉 둘째 칸을 기준으로 따지면 쉽다: [0][1]
                if board[i][j] == "W" { //👉 둘째칸이 W이면
                    result1 += 1 //👉 WBWB 패턴 다시 칠하기
                } else { //👉 둘째칸이 B이면
                    result2 += 1 //👉 BWBW 패턴 다시 칠하기
                }
            }
        }
    }
    return min(result1, result2)
}

// 체스판 크기(8 * 8)만큼 잘라오는 함수
func getBoard(x: Int, y: Int) -> Board {
    var board = [Array<Character>]()
    for i in 0..<8 {
        board.append(Array(input[x + i][y..<y+8]))
        //⭐️ subscript로 Array의 일부를 가져온 경우
        //👉 SubArray 타입이 되므로 Array로 다시 타입캐스팅해서 사용하자!
    }
    return board
}

// 최대로 다시 칠해야하는 경우로 시작
var result = 64

// 모든 체스판이 나올 수 있는 경우의 수를 순회하면서 최소한으로 다시 칠하는 경우를 구한다.
for x in 0..<(N-7) {
    for y in 0..<(M-7) {
        let board = getBoard(x: x, y: y)
        result = min(result, countRepaint(board: board))
    }
}

print(result)
  1. 주어진 입력에 특정한 규칙이 없으므로 모든 경우의 수를 계산해서 푸는 문제입니다.
  2. 다시 칠하는 칸을 계산하는 함수를 만듭니다.
    1. 체스판은 체스판은 BWBW로 반복되거나 WBWB로 반복되는 구조이므로
    2. 각각의 경우에 맞추어 다시 칠해야하는 칸을 센 후
    3. 둘 중에 작은 수를 리턴합니다.
  3. [x][y]를 기준으로 체스판을 잘라오는 함수를 만듭니다.
  4. 모든 경우의 수를 순회하면서 답을 구합니다.
profile
백과사전 보다 항해일지(혹은 표류일지)를 지향합니다.

0개의 댓글