본문 바로가기
Nodejs로 알고리즘 박살내기

백준 2668 숫자고르기

by heesu 2022. 5. 27.
 

2668번: 숫자고르기

세로 두 줄, 가로로 N개의 칸으로 이루어진 표가 있다. 첫째 줄의 각 칸에는 정수 1, 2, …, N이 차례대로 들어 있고 둘째 줄의 각 칸에는 1이상 N이하인 정수가 들어 있다. 첫째 줄에서 숫자를 적절

www.acmicpc.net

예제

간단히 예제를 살펴보면 싸이클이 발생한 구간 1, 3, 5를 순서대로 출력하면 됩니다.

즉. 무한 싸이클이 발생하는 구간의 정수들을 모두 순서대로 출력해주면 됩니다.

 

1. 깊이 우선 탐색(DFS) 알고리즘을 이용해 싸이클이 발생하는지 확인합니다.

 

2. 싸이클이 발생하였다면, 그 때 방문했던 모든 노드들은 정답이 되기때문에 'check'배열에 따로 저장해주겠습니다.

 

3. 위와 같이 N개의 노드를 탐색하면 되는데, 이전에 싸이클이 발생했던 구간(check[n] === true)의 경우 이미 자신을 제외한 다른 싸이클에 속해있다는 의미로 다시 방문해 줄 필요가 없습니다. 따라서 바로 return false; 해주었습니다.

const readline = require("readline");
const rl = readline.createInterface({
  input: process.stdin,
  output: process.stdout,
});

let N;
let input = [0];
let visit = [];
let check = []; // 싸이클에 속한 노드들 체크하는 배열

function dfs(node, target) {
  if (check[node]) return false;
  if (!visit[node]) {
    visit[node] = true;
    return dfs(input[node], target);
  }

  if (node === target) {
    return true;
  }

  return false;
}

rl.on("line", function (line) {
  if (!N) {
    N = +line;
    check = Array.from({ length: N + 1 }, () => false);
  } else {
    input.push(+line);

    if (input.length === N + 1) {
      let result = [];
      for (let i = 1; i <= N; i++) {
        visit = Array.from({ length: N + 1 }, () => false);
        const isCycle = dfs(i, i);

        if (isCycle) {
          for (let j = 1; j <= N; j++) {
            if (visit[j]) {
              check[j] = true;
            }
          }
        }
      }

      for (let i = 1; i < check.length; i++) {
        if (check[i]) result.push(i);
      }
      result.unshift(result.length);
      console.log(result.join("\n"));
      rl.close();
    }
  }
});

'Nodejs로 알고리즘 박살내기' 카테고리의 다른 글

백준 17472 다리 만들기2  (0) 2022.05.28
백준 17090 미로 탈출하기  (0) 2022.05.27
백준 5719 거의 최단 경로  (0) 2022.05.22
백준 2212 센서 js  (0) 2022.05.18
백준 1461 도서관 js  (0) 2022.05.17

댓글