문제

0과 1로만 이루어진 행렬 A와 행렬 B가 있다. 이때, 행렬 A를 행렬 B로 바꾸는데 필요한 연산의 횟수의 최솟값을 구하는 프로그램을 작성하시오.

행렬을 변환하는 연산은 어떤 3 ×3 크기의 부분 행렬에 있는 모든 원소를 뒤집는 것이다. (0 → 1, 1 → 0)

입력

첫째 줄에 행렬의 크기 N M이 주어진다. N과 M은 50보다 작거나 같은 자연수이다. 둘째 줄부터 N개의 줄에는 행렬 A가 주어지고, 그다음줄부터 N개의 줄에는 행렬 B가 주어진다.

출력

첫째 줄에 문제의 정답을 출력한다. 만약 A를 B로 바꿀 수 없다면 -1을 출력한다.

내가 푼 풀이

- 0과 1로 이루어진 행렬을 변환하는 연산은 3x3크기의 부분행렬의 모든원소를 뒤집는 것이다.

- 주어진 행렬이 연산이 불가능한 경우: N < 3 , M < 3

- 이 문제는 한 원소를 기준으로 3x3의 부분 원소를 변환했다.

- 행렬이 1행 1열 -> 1행 m열 -> n행 m열 순으로 인덱스를 접근한다면, 이미 접근한 인덱스는 연산이 이미 완료됐다고 본다.

- 인덱스로 접근할 때 행렬 A[n][m] 값과 B[n][m]값이 다르다면, n과 m기준으로 3x3의 부분행렬을 연산한다.

- n-2행 m-2열까지 모두 순회 후, 연산결과 출력

 

import Foundation

let inputs = readLine()!.split(separator: " ").map{ Int($0)! }
var a = [[String]]()
var b = [[String]]()
var result = 0

// 배열 입력받기
for i in 1...inputs[0]*2 {
    var arr = Array(readLine()!).map{ String($0) }
    if i <= inputs[0] {
        a.append(arr)
    } else {
        b.append(arr)
    }
}

// 배열의 크기가 연산가능한 크기보다 작다면
// 배열 a 와 b가 서로 다르다면, a는 b가 될 수 없으므로 -1
// 배열 a 와 b가 서로 같다면, a는 이미 b이므로 0 출력
if a.count < 3 || a[0].count < 3 {
    for i in 0..<a.count {
        let arr1 = a[i]
        let arr2 = b[i]
        if a[i] != b[i] {
            result = -1
        }
    }
    print(result)
} else {
    // 행은 n-2 까지, 열은 m-2 까지 순회
    // a[n][m] != b[n][m] 이면 연산
    for i in 0..<a.count-2 {
        for j in 0..<a[0].count-2 {
            var str1 = a[i][j]
            var str2 = b[i][j]

            if str1 == str2 {
                continue
            } else {
                result += 1
                for k in 0..<3 {
                    for n in 0..<3 {
                        if a[i+k][j+n] == "1" {
                            a[i+k][j+n] = "0"
                        } else {
                            a[i+k][j+n] = "1"
                        }
                    }
                }
            }
        }
    }
    
    // 연산결과 a와 b가 완전히 같은지 비교
    for i in 0..<a.count {
        let arr1 = a[i]
        let arr2 = b[i]
        
        if a[i] != b[i] {
            result = -1
        }
    }

    print(result)

}

'코딩테스트 > 백준' 카테고리의 다른 글

BOJ-2293 동전 1 Swift  (0) 2023.05.18
BOJ-2437 저울 Swift  (0) 2023.05.18
BOJ-9465 스티커 Swift  (1) 2023.05.17
BOJ-2864 5와 6의 차이 Swift  (1) 2023.05.17
BOJ-11000 강의실 배정 Swift  (1) 2023.05.17

+ Recent posts