[백준] 2980 도로와 신호등 JavaScript

·2024년 4월 12일

문제

상근이는 트럭을 가지고 긴 일직선 도로를 운전하고 있다. 도로에는 신호등이 설치되어 있다. 상근이는 각 신호등에 대해서 빨간 불이 지속되는 시간과 초록 불이 지속되는 시간을 미리 구해왔다. (빨강색과 초록색 불빛은 무한히 반복된다)

상근이의 트럭이 도로에 진입했을 때, 모든 신호등의 색상은 빨간색이고, 사이클이 막 시작한 상태이다. 상근이는 1초에 1미터를 움직인다. 신호등의 색상이 빨간색인 경우에는 그 자리에서 멈추고 초록색으로 바뀔때 까지 기다린다.

상근이가 도로의 끝까지 이동하는데 걸리는 시간을 구하는 프로그램을 작성하시오. 도로의 시작은 0미터이고, 끝은 L미터인 지점이다.

입력

첫째 줄에 신호등의 개수 N과 도로의 길이 L이 주어진다. (1 ≤ N ≤ 100, 1 ≤ L ≤ 1000)

다음 N개 줄에는 각 신호등의 정보 D, R, G가 주어진다. (1 ≤ D < L, 1 ≤ R ≤ 100, 1 ≤ G ≤ 100) D는 신호등의 위치이며, R과 G는 빨간색, 초록색이 지속되는 시간이다.

신호등은 D가 증가하는 순서로 주어지며, 같은 위치에 있는 신호등이 두 개 이상 있는 경우는 없다.

출력

첫째 줄에 상근이가 도로의 끝까지 이동하는데 걸리는 시간을 출력한다.

예제 입력

2 10
3 5 5
5 2 2

예제 출력

12

내가 했던 풀이 방법

  1. 입력받은 신호등의 정보를 공백을 기준으로 분할하여 배열로 변환해준다.
  2. 0m부터 Lm 전까지 거리를 1씩 증가시키면서 시간을 계산한다. 현재 위치에 신호등이 없을 경우 time을 1씩 증가시켜준다. (신호등 정보 중 D를 이용하여 배열의 D가 현재 거리와 일치하지 않을 경우 신호등이 현재 위치에 존재하지 않는다.)
  3. 현재 위치에 신호등이 있을 경우 현재 신호등을 검사한다. 신호등은 빨간불 지속시간+초록불 지속시간 동안 켜져있으므로 R과 G를 더한 값을 간격으로 신호등이 빨간 불이 되는 점을 이용한다. 현재 시간을 신호등의 지속시간으로 나눈 나머지가 현재 신호등이 다시 빨간 불이 될 때까지 남은 시간이다. 남은 시간이 R과 같거나 작을 경우 현재 신호등은 빨간 불이다. 그러므로 빨간불 지속시간에서 남은 시간을 빼준 시간이 기다려야 하는 시간이다. (0초 대기하는 건 없으므로 +1을 해주어야 한다.)
  4. 현재 위치에 신호등이 있지만 빨간 불이 아닐 경우 2번과 같이 time을 1씩 증가시켜준다.
  5. 현재 위치에 신호등이 있던 경우 (3번과 4번) traffic_light(신호등 배열 index 변수)를 1 증가시켜준다. 신호등이 오름차순으로 주어지기 때문에 첫 배열부터 검사해주고, 해당 신호등을 지나쳤을 경우 다음 배열을 검사해주는 방법으로 계산한다. (신호등은 마지막 위치까지 존재하지 않을 수 있기 때문에 마지막 신호등을 지나칠 경우 traffic_light가 index보다 커지게 되어 index 오류를 발생할 수 있으므로, 신호등을 검사하기 전 traffic_light 값의 유효성을 먼저 검사해주어야 한다.)

코드

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

let N = parseInt(n.split(' ')[0].trim());
let L = parseInt(n.split(' ')[1].trim());

for (let i = 0; i < input.length; i++) {
  input[i] = input[i].trim().split(' ');
}
let time = 0;
let traffic_light = 0;
let turn = 0;
let remaining = 0;

for (let i = 0; i < L; i++) {
  if (traffic_light < input.length && i === parseInt(input[traffic_light][0])) {
    turn = parseInt(input[traffic_light][1]) + parseInt(input[traffic_light][2]);
    remaining = time % turn;
    if (remaining <= parseInt(input[traffic_light][1])) {
      time += parseInt(input[traffic_light][1]) - remaining + 1;
    } else {
      time++;
    }
    traffic_light++;
  } else {
    time++;
  }
}

console.log(time);

회고

아이디어는 생각보다 금방 떠올랐는데 변수하나 잘못 둬서 시간이 좀 걸렸던 문제.... 현재 시간을 신호등 간격으로 나눠주어야 하는데 현재 위치를 신호등 간격으로 나눠주었다. (이랬는데 문제랑 반례들은 왜 다 제대로 출력된건지 알다가도 모르겠다.) 아이디어가 금방 안 떠올랐으면 지금보다도 굉~장히 오래 풀거나 코드가 길어지지 않았을까.. 그나마 다행이다.

profile
Frontend🍓

0개의 댓글