[백준 1080번] 그리디 알고리즘 - 행렬

김민지·2023년 7월 12일
0

냅다 시작 백준

목록 보기
52/118

✨ 문제 ✨

✨ 정답 ✨

const fs = require("fs");
const filePath = process.platform === "linux" ? "/dev/stdin" : "./예제.txt";
let input = fs.readFileSync(filePath).toString().trim();
// const fs = require('fs'); 
// let input = fs.readFileSync('/dev/stdin').toString().trim();

input=input.split('\n')
let N=+input[0].split(' ')[0]
let M=+input[0].split(' ')[1]

let A=input.slice(1, N+1)
A=A.map((el)=>el.trim().split('').map((el)=>+el))
let B=input.slice(N+1)
B=B.map((el)=>el.trim().split('').map((el)=>+el))



//테이블 값 변환
const flip=(x, y)=>{
    for(let i=x; i<x+3; i++){
        for(let j=y; j<y+3; j++){
            A[i][j] = 1 - A[i][j];
        }
    }
}


const solution= (N, M, A, B)=>{
    let count=0;
    // 뒤집을지 결정하는 과정: 왼쪽 최상단 값 비교해야 함.   
    // N과 M이 3 미만인 경우에는 애초에 아래의 for문이 돌아가지 않음.
    for (let i=0;i<N-2;i++){
        for (let j=0;j<M-2;j++){
            if (A[i][j]!==B[i][j]){
                flip(i, j)
                count+=1;
            }

        }
    }
    // A와 B가 완벽하게 같은 행렬인지 체크하는 부분.
    for (let i=0;i<N;i++){
        for (let j=0;j<M;j++){
            if (A[i][j]!==B[i][j]){
                count=-1;
                break;
            }
        }
    }
    return count
}

console.log(solution(N, M , A, B))

🧵 참고한 정답지 🧵

https://ghost4551.tistory.com/14

💡💡 기억해야 할 점 💡💡

  1. 3×3크기의 부분 행렬에 있는 모든 원소를 뒤집는 것이라고 했으니 3x3 행렬의 맨 왼쪽 최상단 원소만 비교하면 뒤집을지 안 뒤집을지 결정할 수 있다. 두번째, 세번째 줄의 맨 왼쪽 원소들은 어차피 맨 위의 원소와 운명을 같이 하기 때문이다.
    --> 처음에는 이렇게 풀면 4줄 이상의 행렬에서는 문제가 생기지 않나 생각했는데 참고한 정답지를 보니, 결국 행도 0부터 M-2까지 체크를 하더라.
  2. M과 N이 3 미만일 경우에는 무조건 -1을 출력하도록 조건문으로 따로 처리를 해야 하나 했는데, 정답지 작성자분께서 이러한 경우는 애초에 원소 체크 for문에도 들어가지 않게 처리를 아주 깔끔하게 하셨다.
profile
이건 대체 어떻게 만든 거지?

0개의 댓글