• TOC {:toc}

이 글은 백준 온라인 저지의 1080번 문제를 자바스크립트(JavaScript)으로 풀이한 것을 모아놓은 글입니다.

일종의 연습 기록이며 제가 정답을 받은 코드와 참고할만한 다른 코드를 같이 기록합니다. 필요한 경우 코드에 대한 해설을 기록합니다만 코드는 통과했어도 해설은 틀릴 수 있기 때문에 가볍게 참고해주시길 부탁드립니다. 피드백은 편하신 방법으로 자유롭게 주시면 감사하겠습니다.

2023.02.28

메모리 시간 코드 길이
10204 KB 184 ms 1528 B
단계 시작 시각 끝난 시각 걸린 시간
문제 이해 13:03:04 13:05:11
풀이 생각 13:05:12 13:12:44
코딩 14:45:36 15:14:38
디버깅 15:38:31 15:52:41
const fs = require("fs");
const input = fs.readFileSync('/dev/stdin').toString().trim().split("\n");

const [NM, ...lines] = input;
const [N, M] = NM.split(" ").map((n) => parseInt(n));
const matrices = lines.map((line) => [...line]);

function convert(matrix, i, j) {
    for (let m = 0; m < 3; m += 1) {
        for (let n = 0; n < 3; n += 1) {
            matrix[i + m][j + n] = !matrix[i + m][j + n];
        }
    }
}

function countConvert(matrix) {
    if (N < 3 || M < 3) {
        for (let i = 0; i < N; i += 1) {
            for (let j = 0; j < M; j += 1) {
                if (!matrix[i][j]) {
                    return -1;
                }
            }
        }
        return 0;
    }

    let count = 0;
    for (let i = 0; i < N - 2; i += 1) {
        for (let j = 0; j < M - 2; j += 1) {
            if (!matrix[i][j]) {
                convert(matrix, i, j);
                count += 1;
            }
        }
    }

    for (let i = 0; i < N; i += 1) {
        for (let j = 0; j < M; j += 1) {
            if (!matrix[i][j]) {
                return -1;
            }
        }
    }
    return count;
}

function main() {
    const isSame = [];
    for (let i = 0; i < N; i += 1) {
        const tmp = [];
        for (let j = 0; j < M; j += 1) {
            if (matrices[i][j] === matrices[i + N][j]) {
                tmp.push(true);
            } else {
                tmp.push(false);
            }
        }
        isSame.push(tmp);
    }

    return countConvert(isSame);
}

console.log(main());

아이디어 & 풀이

행렬의 각 항을 순회하면서 해당 항의 값이 A와 B에서 다르면 연산을 수행한다.

  • 연산을 수행할 때마다 count의 값을 1씩 증가시킨다.
  • 두 행렬의 항이 같은지의 여부를 true, false로 나타내는 isSame 배열을 별도로 정의해 사용했다.

마지막 항(N - 2, M - 2)까지 검사해 연산을 끝내면 모든 항이 같은지 여부를 검사한다.

  • 모든 항이 같으면 위에서 계산한 count
  • 같지 않으면 -1을 출력한다.

N과 M이 3미만인 경우는 행렬을 부분적으로 뒤집는 것이 불가능하므로 각 행렬의 값만 비교한다.

  • 모든 항이 같으면 0을, 같지 않으면 -1을 출력한다.

디버그

  • 연산 여부를 결정하기 위해 확인하는 항 외에도 행들이 존재하므로 연산이 끝난 후에 항을 전체적으로 검사를 해주어야 하는데 그 과정을 빼먹어서 틀렸다.

참고 답안

const fs = require("fs");
const input = fs.readFileSync('/dev/stdin').toString().trim().split("\n");

const [NM, ...lines] = input;
const [N, M] = NM.split(" ").map((n) => parseInt(n));

const A = lines.slice(0, N).map(line => line.split("").map(n => parseInt(n)));
const B = lines.slice(N).map(line => line.split("").map(n => parseInt(n)));

function main() {
    let count = 0;

    for (let i = 0; i < N - 2; i += 1) {
        for (let j = 0; j < M - 2; j += 1) {
            if (A[i][j] !== B[i][j]) {
                for (let k = 0; k < 3; k += 1) {
                    for (let l = 0; l < 3; l += 1) {
                        A[i + k][j + l] = 1 - A[i + k][j + l];
                    }
                }
                count += 1;
            };
        }
    }

    for (let i = 0; i < N; i += 1) {
        for (let j = 0; j < M; j += 1) {
            if (A[i][j] !== B[i][j]) {
                return -1;
            }
        }
    }
    return count
}

console.log(main());

아이디어 & 풀이

  • 로직 자체는 위의 풀이와 유사하지만 AB 행렬을 직접 비교하면서 A 행렬의 값을 바꾸는 방식을 사용한다.