[JS] 백준 22352 항체 인식

yoon·2024년 5월 28일

코딩테스트

목록 보기
8/8

공식은 단순히 dfs를 쓰면 되는데 조건들을 자세하게 설정해야 한다.
나는 항체가 생기기 전, 후의 배열을 각각 구하고 몇 번 째 행, 열이 처음으로 바뀌었는지 값과 바뀐 항체 값을 구했다. (바뀌지 않았다면 early return)

그 이후에는 visited 배열을 선언하여 상하좌우로 이동 가능한 경우 && 방문하지 않은 경우 && 전 값과 같은 경우에만 재귀를 하도록 했다.
전 값과 같은 경우로 한 이유는 dfs의 첫 시작이 백신을 놓아 항체가 생긴 행, 열 값이기 때문에 이 시작하는 행, 열의 값과 동일한 값일 때만 순회해야 한다.
그리고 순회하며 visited 값을 true로 만들어서 업데이트되기 전 배열에서 항체가 생겨야 하는 부분이 어느 부분인지를 알아내야 한다. 이 값을 토대로 업데이트된 배열과 비교해야 한다.

순회가 끝나면 다시 배열을 순회하며 백신이 맞는지 판단하는 조건을 추가하면 된다.
백신이 안 되는 조건은 다음과 같다.

  1. 전, 후의 값이 다르고(다르다면 반드시 업데이트된 값이어야 함) 업데이트된 값인데 방문하지 않는 경우
  2. 방문했는데 업데이트된 값이 아닌 경우
  3. 전, 후의 값이 다른데(다르다면 반드시 업데이트된 값이어야 함) 업데이트된 값이 아닌 경우
const fs = require("fs");
let input = fs.readFileSync("dev/stdin").toString().trim().split("\n");

const [N, M] = input[0].split(" ").map(Number);
const before = input.slice(1, N + 1).map((str) => str.split(" ").map(Number));
const after = input.slice(N + 1).map((str) => str.split(" ").map(Number));
let answer = "YES";
let [row, col] = [-1, -1];
let changedNum = -1;
for (let i = 0; i < N; i++) {
  for (let j = 0; j < M; j++) {
    if (before[i][j] !== after[i][j]) {
      [row, col] = [i, j];
      changedNum = after[i][j];
      break;
    }
  }
}

// 전, 후가 같은 경우
if (changedNum === -1) {
  console.log(answer);
  return;
}

const visited = new Array(N).fill("").map(() => new Array(M).fill(false));
const direction = [
  [0, 1],
  [1, 0],
  [0, -1],
  [-1, 0],
];
const isValid = (row, col) => row >= 0 && row < N && col >= 0 && col < M;
const dfs = (row, col) => {
  if (visited[row][col]) return;
  visited[row][col] = true;
  for (const [x, y] of direction) {
    if (
      !isValid(row + x, col + y) ||
      visited[row + x][col + y] ||
      before[row][col] !== before[row + x][col + y]
    ) {
      continue;
    }
    dfs(row + x, col + y);
  }
};
dfs(row, col);

for (let i = 0; i < N; i++) {
  for (let j = 0; j < M; j++) {
    if (
      (after[i][j] === changedNum &&
        before[i][j] !== after[i][j] &&
        !visited[i][j]) ||
      (after[i][j] !== changedNum &&
        (visited[i][j] || before[i][j] !== after[i][j]))
    ) {
      answer = "NO";
      break;
    }
  }
  if (answer === "NO") break;
}

console.log(answer);

결과

profile
얼레벌레 개발자

0개의 댓글