백준 3020 개똥벌레

2022. 1. 12. 20:07·Nodejs로 알고리즘 박살내기

문제

 

3020번: 개똥벌레

개똥벌레 한 마리가 장애물(석순과 종유석)로 가득찬 동굴에 들어갔다. 동굴의 길이는 N미터이고, 높이는 H미터이다. (N은 짝수) 첫 번째 장애물은 항상 석순이고, 그 다음에는 종유석과 석순이

www.acmicpc.net

 

풀이

결론부터 본다면 구간별로 장애물을 파괴한 개수를 배열에 담은 후, 최소가 되는 값과 그 값의 개수가 답이 됩니다.

 

위와 같이 문제가 주어질 때 4 구간에 장애물이 파괴되기 위한 조건으로는 아래와 같습니다.

  1. 종유석의 경우 높이가 4보다 크거나 같아야 한다.
  2. 석순의 경우 전체 높이에서 4를 뺀 것보다 1 이상 커야 한다.

즉 4 구간의 장애물이 파괴한 개수 = 종유석이 높이 4보다 크거나 같은 갯수 + 석순이 전체 높이에서 4를 뺀 것보다 1 이상 큰 개수가 되는 것입니다.

 

과정

1. 석순과 종유석 각각의 배열에 해당 높이의 개수가 몇 개인지 입력받아줍니다.

let W, H;
let top = []; // 석순
let bot = []; // 종유석
let idx = 0;

rl.on('line', function (line) {
  if(!W) {
    [W, H] = line.split(' ').map(n => +n);
    top = Array.from({ length: H + 1 }, () => 0);
    bot = Array.from({ length: H + 1 }, () => 0);
  } else {
    if(idx % 2 === 0) {
      bot[+line]++;
    } else {
      top[+line]++;
    }
    
    if(++idx === W) rl.close();
  }
})

2. 부분 합을 통해 전체 높이를 기준하여 역으로 높이가 n보다 크거나 같은 개수를 배열에 담아줍니다.

원리는 간단합니다.

n의 높이보다 크거나 같은 장애물의 갯수 = n + 1보다 크거나 같은 갯수 + n의 높이 개수입니다.

  let sum_top = [];
  let sum_bot = [];
  let cnt = 0;

  for(let i = H; i > 0; i--) {
    sum_top[i] = (sum_top[i + 1] ?? 0) + top[i];
    sum_bot[i] = (sum_bot[i + 1] ?? 0) + bot[i];
  }

3. 2번 과정에서 증류석이 각각의 높이보다 크거나 같은 개수를 정리하였으므로, 거기서 석순이

전체 높이에서 각각의 높이를 뺀 것보다 1이 더 큰 높이 개수를 더해줍니다. 

 

동시에 

2 ≤ N ≤ 200,000이기 때문에 최솟값을 max(200,000) 값으로 할당해줍니다.

최솟값이 되는 개수를 출력하기위해 최솟값을 할당하고 갯수를 count 해줍니다.

  let cnt = 0;
  let min = 200000;

  for(let i = H; i > 0; i--) {
    sum_bot[i] = sum_bot[i] + sum_top[H - i + 1];

    if(sum_bot[i] < min) {
      min = sum_bot[i];
      cnt = 1;
    } else if(sum_bot[i] === min) {
      cnt++;
    }
  }

 

최종 코드

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

let W, H;
let top = []; // 석순
let bot = []; // 종유석
let idx = 0;

rl.on('line', function (line) {
  if(!W) {
    [W, H] = line.split(' ').map(n => +n);
    top = Array.from({ length: H + 1 }, () => 0);
    bot = Array.from({ length: H + 1 }, () => 0);
  } else {
    if(idx % 2 === 0) {
      bot[+line]++;
    } else {
      top[+line]++;
    }
    
    if(++idx === W) rl.close();
  }
})

.on('close', function () {
  let sum_top = [];
  let sum_bot = [];
  
  for(let i = H; i > 0; i--) {
    sum_top[i] = (sum_top[i + 1] ?? 0) + top[i];
    sum_bot[i] = (sum_bot[i + 1] ?? 0) + bot[i];
  }
  
  let min = 200000;
  let cnt = 0;

  for(let i = H; i > 0; i--) {
    sum_bot[i] = sum_bot[i] + sum_top[H - i + 1];

    if(sum_bot[i] < min) {
      min = sum_bot[i];
      cnt = 1;
    } else if(sum_bot[i] === min) {
      cnt++;
    }
  }

  console.log(min, cnt);
  process.exit();
});
저작자표시 (새창열림)

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

프로그래머스 LV.4 지형 이동 js  (1) 2022.03.11
백준 4386 별자리 만들기 js  (0) 2022.03.09
백준 1738 골목길 js  (0) 2022.03.09
백준 2493 탑 js  (0) 2022.01.15
백준 2473 세 용액 js  (0) 2022.01.13
'Nodejs로 알고리즘 박살내기' 카테고리의 다른 글
  • 백준 4386 별자리 만들기 js
  • 백준 1738 골목길 js
  • 백준 2493 탑 js
  • 백준 2473 세 용액 js
heesu
heesu
개발하면서 겪었던 경험을 공유합니다.
  • heesu
    heesu dev
    heesu
  • 전체
    오늘
    어제
    • 분류 전체보기
      • Nodejs로 알고리즘 박살내기
      • 사이드 프로젝트
        • Bitfolio
      • React Native
      • Etc
      • HTML
      • NextJS
      • Javascript
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

  • 공지사항

  • 인기 글

  • 태그

    프로그래머스
    BFS
    크루스칼
    투 포인터
    asyncstorage
    Animated
    학습
    letsencrypt
    정렬
    react-native
    UnionFind
    부분합
    크루스칼 알고리즘
    React Native
    완전 탐색
    Dijkstra
    union-find
    벨만포드 알고리즘
    우선순위 큐
    최소 스패닝
    Nodejs
    redux-persist
    cleancode
    dfs
    certbot
    lv4
    백준
    JavaScript
    알고리즘
    시맨틱 태그
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.3
heesu
백준 3020 개똥벌레
상단으로

티스토리툴바