jiho_bae
Go devlog
jiho_bae
전체 방문자
오늘
어제
  • 분류 전체보기 (158)
    • JavaScript (38)
      • theory (34)
      • vanilla (4)
    • HTML & CSS (2)
    • Browser (3)
    • CS (6)
      • linux (1)
      • shell (2)
      • compiler (2)
    • DS & Algorithm (87)
      • theory (5)
      • basic (7)
      • programmers (30)
      • baekjoon (45)
    • Design Pattern (2)
    • Error (4)
    • Git & Github (4)
    • Tools (1)
    • 부트캠프 (4)
    • Small Tips (2)
    • Java (3)
    • test (1)

블로그 메뉴

  • 홈
  • 태그
  • 방명록

공지사항

인기 글

태그

  • 자바스크립트 모듈 시스템
  • 계수정렬 자바스크립트
  • 13460 javascript nodejs
  • 억억단을 외우자 javascript
  • 자바스크립트 비동기 마이크로 태스크 큐와 렌더링 과정
  • safari invalid date error
  • 덧칠하기 javascript
  • 자바스크립트 이벤트 위임
  • 카카오 코딩테스트 양궁대회 nodeJS
  • 프로그래머스 숫자카드나누기 javascript
  • 리코쳇 로봇 javascript
  • 백준 17406 nodeJS
  • 25632 소수 부르기 게임
  • 대충만든자판 javascript
  • 1753 최단경로 javascript
  • 백준 자바스크립트 입력 템플릿
  • 깃 이전 커밋에서 새 브랜치 만들기
  • safari Date format NaN
  • javascript use strict
  • JavaScript
  • 외벽 점검 javascript
  • 자바스크립트 커링
  • 병합정렬 자바스크립트
  • 퀵정렬 자바스크립트
  • fetch 취소하기
  • 자바스크립트 채팅방 스크롤
  • 가사 검색 자바스크립트
  • 자바스크립트 sort는 왜 그모양일까
  • 리액트 프로젝트 디버깅하기
  • 자바스크립트 배열의 특수함

최근 댓글

최근 글

티스토리

hELLO · Designed By 정상우.
jiho_bae
DS & Algorithm/baekjoon

[백준] 13023번 ABCDE - JavaScript(NodeJS)

[백준] 13023번 ABCDE - JavaScript(NodeJS)
DS & Algorithm/baekjoon

[백준] 13023번 ABCDE - JavaScript(NodeJS)

2021. 5. 27. 03:56

문제

 

13023번: ABCDE

문제의 조건에 맞는 A, B, C, D, E가 존재하면 1을 없으면 0을 출력한다.

www.acmicpc.net

 

풀이

상당히 고생했던 문제이다.

 

이 문제는,

A와 B가 친구, B와 C가 친구, C와 D가 친구, D와 E가 친구인 경우가 존재하는지 구하면 된다.

우측과 같이 연속된 5명의 관계를 발견하면 된다.

 

그림과 같이 특정 노드에서 시작해서, 중복되지 않는 노드로 4번 이동할 수 있다면 (총 5개의 노드를 방문하면) 된다.

DFS를 이용할 것이며, 그래프의 연결관계 표현을 위해 인접행렬을 이용하자.

 

변수 소개

각 변수들은 아래에 작성한 코드를 참고하자.

 

N, M : 문제의 조건인 사람의 수(N), 관계의 수(M)
adjM : N * N 인접행렬
check : 방문한 노드를 재방문하지 않기 위한 배열. 방문시 1, 미방문시 0
flag : 정답을 발견했을 때 재귀를 빠르게 종료하기 위한 변수
dfs : DFS를 위한 함수. L은 현재 노드(사람), cnt는 서로 노드 간 연속 이동 횟수

 

코드

const sol = (input) => {
  const [N, M] = input[0].split(" ").map((v) => +v);
  const adjM = Array.from({ length: N }, () => Array(N).fill(0));
  const check = Array.from({ length: N }, () => 0);
  let flag = 0;
  for (let i = 1; i <= M; i++) {
    const [a, b] = input[i].split(" ").map((v) => +v);
    adjM[a][b] = adjM[b][a] = 1;
  }

  const dfs = (L, cnt) => {
    check[L] = 1; // 방문처리를 한다.
    if (flag) return; 
    if (cnt === 4) { // cnt가 4일 시 조건을 만족한다.
      flag = 1;
      return;
    }

    for (let i = 0; i < N; i++) {
      if (adjM[L][i] === 1 && !check[i]) { // 인접한 노드이며, 방문하지 않은 노드일 때 이동한다.
        dfs(i, cnt + 1);
      }
    }
    check[L] = 0; // 방문이 끝났다면 미방문으로 바꾼다.
  };

  for (let i = 0; i < N; i++) {
    dfs(i, 0); // 처음으로 방문할 노드를 선택한다.
  }
  return flag; // flag가 있다면(검출되었다면) 1을 출력, 아니라면 0을 출력.
};

// 이 아래로는 백준 저지에서 입력을 받기 위한 코드
const input = [];
require("readline")
  .createInterface(process.stdin, process.stdout)
  .on("line", (line) => {
    input.push(line);
  })
  .on("close", () => {
    console.log(sol(input));
    process.exit();
  });

최종적으로 다음과 같이 코드를 작성했다.

 

작성한 글의 흐름으로 보면, 바로 문제를 해결한 듯 보이나...

사실 무수한 실패 메시지가 떴었고 결국엔 시간초과 이슈로 좌절했던 문제다.

 

 

 

사람의 수 N (5 ≤ N ≤ 2000)과 친구 관계의 수 M (1 ≤ M ≤ 2000)

문제 조건을 다시 보며 고민을 하던 중 기억 저 멀리 인접 리스트가 생각이 났다.

인접리스트를 적용해보자.

 

인접리스트

인접행렬이 N * N 크기로 노드 간 연결 관계를 표현했다면,
인접리스트는 N * k 크기로 각 노드에 연결된 노드만을 리스트에 담은 것이다.

 

(0, 1), (0, 3), (1, 3)의 연결관계가 있다고 가정하고,
인접행렬과 인접리스트로 각각 나타내보면

 

인접행렬

0 [0, 1, 0, 1]
1 [1, 0, 0, 1]
2 [0, 0, 0, 0]
3 [1, 1, 0, 0]

인접리스트

0 [1, 3]
1 [0, 3]
2 []
3 [0, 1]

다음과 같이 표현한다.

 

표현해야 할 노드가 많아질 수록, 인접리스트가 유리할 것임은 분명하다.

 

아무튼 인접리스트를 선언해서, 다시 정보를 담은 후 dfs를 실행해보자.

 

인접리스트 코드

const sol = (input) => {
  const [N, M] = input[0].split(" ").map((v) => +v);
  const adjArr = Array.from({length:N}, ()=>Array(0)}; // N개의 행을 가지며 행마다 빈 배열을 하나씩 가진다.
  const check = new Array(N).fill(0);
  let flag = 0;
  for (let i = 1; i <= M; i++) {
    const [a, b] = input[i].split(" ").map((v) => +v);
    adjArr[a].push(b);
    adjArr[b].push(a);
  } // 인접리스트에 a->b, b->a 관계를 각각 넣어준다.

  const dfs = (L, cnt) => {
    if (flag) return; // 조건을 만족하면 빠르게 재귀를 종료하기 위한 조건문.
    check[L] = 1; // 노드를 방문한다.
    if (cnt === 4) {
      flag = 1;
      return;
    }

    for (let i = 0; i < adjArr[L].length; i++) { // 현재 노드의 인접리스트인 addArr[L] 크기 이용
      const next = adjArr[L][i]; // 다음에 이동할 수도 있는 노드
      if (!check[next]) { // next 노드에 방문하지 않았다면, 방문하자.
        dfs(next, cnt + 1);
      }
    }
    check[L] = 0; // 방문했던 노드는 다시 미방문 처리한다.
  };

  for (let j = 0; j < N; j++) {
    dfs(j, 0); // 처음 방문할 노드를 선택한다.
  }
  return flag;
};

const input = [];
require("readline")
  .createInterface(process.stdin, process.stdout)
  .on("line", (line) => {
    input.push(line);
  })
  .on("close", () => {
    console.log(sol(input));
    process.exit();
  });

다음과 같이 인접 리스트를 이용하면, 시간초과 이슈 없이 문제를 해결할 수 있다.

저작자표시 (새창열림)

'DS & Algorithm > baekjoon' 카테고리의 다른 글

[백준] 7576번 토마토 - JavaScript(NodeJS)  (0) 2021.05.28
[백준] 2178번 미로 -JavaScript(NodeJS)  (0) 2021.05.28
[백준] 1932번 정수삼각형 - JavaScript(NodeJS)  (0) 2021.05.17
[백준] 1309번 동물원 - JavasScript(NodeJS)  (0) 2021.05.16
[백준] 1406번 에디터 - JavaScript(NodeJS)  (2) 2021.05.02
  • 문제
  •  
  • 풀이
  • 변수 소개
  •  
  • 코드
  •  
  • 인접리스트
  •  
  • 인접리스트 코드
'DS & Algorithm/baekjoon' 카테고리의 다른 글
  • [백준] 7576번 토마토 - JavaScript(NodeJS)
  • [백준] 2178번 미로 -JavaScript(NodeJS)
  • [백준] 1932번 정수삼각형 - JavaScript(NodeJS)
  • [백준] 1309번 동물원 - JavasScript(NodeJS)
jiho_bae
jiho_bae
하루에 한 걸음씩

티스토리툴바

단축키

내 블로그

내 블로그 - 관리자 홈 전환
Q
Q
새 글 쓰기
W
W

블로그 게시글

글 수정 (권한 있는 경우)
E
E
댓글 영역으로 이동
C
C

모든 영역

이 페이지의 URL 복사
S
S
맨 위로 이동
T
T
티스토리 홈 이동
H
H
단축키 안내
Shift + /
⇧ + /

* 단축키는 한글/영문 대소문자로 이용 가능하며, 티스토리 기본 도메인에서만 동작합니다.