본문 바로가기
알고리즘

[Swift 알고리즘] 백준 1180 행렬

by 코코종 2023. 4. 6.
728x90

안녕하세요 코코종입니다.

오늘은 3일차 내용입니닷

너무 어려버서 노트에도 써보고 했는데 안되겠어서 컨닝을 슬~쩍 하고 풀었습니다.

참고로 실패했던 과정도 있으니 한번 같이 생각해보면 좋아요!

//
//  main.swift
//  BackJoon
//
//  Created by kokojong on 2023/04/04.
//

import Foundation
// 1180 행렬 그리디 실1 

// 연산 -> 3*3 행렬의 원소를 모두 뒤집음
// 최소로 연산을 하는 횟수를 return

let input = readLine()!.components(separatedBy: " ").map { Int($0)! }

let n = input[0]
let m = input[1]

var a: [[Int]] = []
var b: [[Int]] = []

for _ in 0..<n {
    a.append(Array(readLine()!).map { Int(String($0))! } )
}

for _ in 0..<n {
    b.append(Array(readLine()!).map { Int(String($0))! } )
}

var result = 0

func isValid(r: Int, c: Int) -> Bool {
    if r + 2 > n || c + 2 > m { return false}
    return true
}

func isDiffrent(r: Int, c: Int) -> Bool {
    for i in r...r+2 {
        for j in c...c+2 {
            if a[i][j] != b[i][j] { return true }
        }
    }
    return true
}

func reverseArrayA(r: Int, c: Int) {
    for i in r...r+2 {
        for j in c...c+2 {
            a[i][j] = (a[i][j] + 1) % 2
        }
    }
    result += 1
}


for r in 0...n-3 {
    for c in 0...m-3 {
        if isValid(r: r, c: c), isDiffrent(r: r, c: c) {
            reverseArrayA(r: r, c: c)
        }
    }
}

if a == b {
    print(result)
} else {
    print(-1)
}

네 이거 그대로 복붙하면 틀려요 왜일까요?? 바로 isDiffrent에서 모든 배열을 다 비교해서 그렇답니다 (멍충이) 3*3으로 고른 부분이 하나라도 다르면 isDiffrent = true 가 되어버리게 해버려서 엉망진창이 되었습니다 ㅋㅋㅋ

//
//  main.swift
//  BackJoon
//
//  Created by kokojong on 2023/04/04.
//

import Foundation
// 1180 행렬 그리디 실1 

// 연산 -> 3*3 행렬의 원소를 모두 뒤집음
// 최소로 연산을 하는 횟수를 return

let input = readLine()!.components(separatedBy: " ").map { Int($0)! }

let n = input[0]
let m = input[1]

var a: [[Int]] = []
var b: [[Int]] = []

for _ in 0..<n {
    a.append(Array(readLine()!).map { Int(String($0))! } )
}

for _ in 0..<n {
    b.append(Array(readLine()!).map { Int(String($0))! } )
}

var result = 0

func isValid(r: Int, c: Int) -> Bool {
    if r + 2 > n || c + 2 > m { return false}
    return true
}

func isDiffrent(r: Int, c: Int) -> Bool {
//    for i in r...r+2 {
//        for j in c...c+2 {
            if a[r][c] != b[r][c] { return true }
//        }
//    }
    return false
}

func reverseArrayA(r: Int, c: Int) {
    for i in r...r+2 {
        for j in c...c+2 {
            a[i][j] = (a[i][j] + 1) % 2
        }
    }
    result += 1
}

func main() -> Int {
    if n < 3 || m < 3 {
        return -1
    }
        
    for r in 0...n-3 {
        for c in 0...m-3 {
            if isValid(r: r, c: c), isDiffrent(r: r, c: c) {
                reverseArrayA(r: r, c: c)
            }
        }
        
        // 해당 행에서 다 바꿨는데 다르다면
        if a[r] != b[r] {
            return -1
        }
    }

    if a == b {
        return result
    } else {
        return -1
    }
}

print(main())

얘는 또 왜 틀렸을까요? 참고로 `if a[r] != b[r] { return -1 }` 부분은 없어도 돌아가나 확인차 해봤습니다! 최적화하는 부분이긴 한데 테스트 해보니 없어도 통과는 되더라구요!

바로... n < 3 || m < 3 이면 -1로 리턴을 했던게 잘못이었습니다... 1*1 행렬로 기존이 0, 원하는게 0 이라고 하면 저 연산을 행하지 않아도 되잖아요? 그런 케이스를 생각을 못했습니다(악랄하다 백준)

//
//  main.swift
//  BackJoon
//
//  Created by kokojong on 2023/04/04.
//

import Foundation
// 1180 행렬 그리디 실1 

// 연산 -> 3*3 행렬의 원소를 모두 뒤집음
// 최소로 연산을 하는 횟수를 return

let input = readLine()!.components(separatedBy: " ").map { Int($0)! }

let n = input[0]
let m = input[1]

var a: [[Int]] = []
var b: [[Int]] = []

for _ in 0..<n {
    a.append(Array(readLine()!).map { Int(String($0))! } )
}

for _ in 0..<n {
    b.append(Array(readLine()!).map { Int(String($0))! } )
}

var result = 0

func isValid(r: Int, c: Int) -> Bool {
    if r + 2 > n || c + 2 > m { return false}
    return true
}

func isDiffrent(r: Int, c: Int) -> Bool {
//    for i in r...r+2 {
//        for j in c...c+2 {
            if a[r][c] != b[r][c] { return true }
//        }
//    }
    return false
}

func reverseArrayA(r: Int, c: Int) {
    for i in r...r+2 {
        for j in c...c+2 {
            a[i][j] = (a[i][j] + 1) % 2
        }
    }
    result += 1
}

func main() -> Int {
    if n < 3 || m < 3 {
        // 무조건 3 이하면 안된다고 생각해서 -1로 리턴했었음.. 어이없서..
        if a == b {
            return result
        } else {
            return -1
        }
    }
        
    for r in 0...n-3 {
        for c in 0...m-3 {
            if isValid(r: r, c: c), isDiffrent(r: r, c: c) {
                reverseArrayA(r: r, c: c)
            }
        }
        
        // 해당 행에서 다 바꿨는데 다르다면
        if a[r] != b[r] {
            return -1
        }
    }

    if a == b {
        return result
    } else {
        return -1
    }
}

print(main())

결국 아래와 같이 성공했답니다.. 추가적으로 중간에 return을 해서 최적화 해야하는 경우가 많아서 main() 을 만들어서 하는 방법을 애용하면 좋을 듯 합니다!

728x90