Algorithm

[Baekjoon]14594번 동방 프로젝트 (Small) - Javascript

호밀이 2024. 2. 1. 17:10

https://www.acmicpc.net/problem/14594

 

14594번: 동방 프로젝트 (Small)

첫 번째 행동으로 1번과 2번 방이 합쳐져 (1, 2), (3), (4), (5) 상태가 된다. 이후 두 번째 행동으로 2, 3, 4번 방이 합쳐져 (1, 2, 3, 4), (5)의 상태가 된다. 따라서 남아있는 동방의 수는 2가 된다.

www.acmicpc.net

문제

동아리방이 가지고 싶었던 병찬이는 LINK 사업단에 문의하여 N개의 방 중의 하나를 얻을 기회를 얻었다. 일자로 되어있는 건물에 N개의 방은 일직선상에 존재하며, 각 방에는 번호가 매겨져 있다. 맨 왼쪽 방의 번호는 1번이며, 순서대로 증가하여 맨 오른쪽 방의 번호가 N번이다. 각 방 사이에는 방을 구분하는 벽이 존재한다.

물론 병찬이 외에도 많은 사람이 동아리방을 원한다. 다행히 방은 충분했기에 병찬이는 안심하고 있었지만…

그때였다.

빅-종빈빌런이 나타나 건물 벽을 허물기 시작한 것이다! 빅-종빈빌런은 다음과 같은 규칙으로 벽을 무너뜨린다.

  • x < y 를 만족하는 두 방에 대해서 x번 방부터 y번 방 사이에 있는 모든 벽을 허문다.
  • 두 방 사이의 벽이 허물어지면 두 방은 하나의 방으로 합쳐진다.
  • 이미 허물어진 벽이 존재한다면 무시하고 다음 벽을 허문다.
  • 빅-종빈빌런은 건물이 무너지는 걸 원치 않기 때문에, 1번 방의 왼쪽 벽과 N번 방의 오른쪽 벽(즉, 바깥과 연결된 벽)은 허물지 않는다.

동아리 방의 개수가 점점 줄어들자 병찬이는 초조해졌다. 이에 병찬이는 동아리방을 얻을 수 있는지에 대한 확률을 계산하기 위해 남는 동아리방의 수를 구하고 싶어 한다. 병찬이를 위해 빅-종빈빌런의 행동 횟수 M과 동방의 개수 N이 주어졌을 때, 남은 동아리방의 수를 구해주자.

입력

첫 번째 줄에는 동아리방의 개수를 나타내는 양의 정수 N(2 ≤ N ≤ 100) 이 주어진다. 두 번째 줄에는 빅-종빈빌런의 행동 횟수를 나타내는 음이 아닌 정수 M(0 ≤ M ≤ 100) 이 주어진다. 세 번째 줄부터 M개의 줄에 걸쳐 빅-종빈빌런의 행동이 양의 정수 x, y(1 ≤ x < y ≤ N) 로 주어진다. 여기서 행동이란 x번 방부터 y번 방 사이의 벽을 무너뜨리는 것을 의미한다.

빅-종빈빌런은 매우 허당이기 때문에 동일한 행동을 여러 번 할 수 있음에 유의하라.

출력

빅-종빈빌런의 모든 행동이 끝난 후 남아있는 동방의 개수를 한 줄에 출력한다.

예제 입력 1 복사

5
2
1 2
2 4

예제 출력 1 복사

2

예제 입력 2 복사

5
1
1 5

예제 출력 2 복사

1

 

문제풀이(1)

동아리방의 개수 = 5, 빅-종빈빌런의 행동횟수 = 2,
빅-종빈빌런의 행동 양의정수 x = 1, 2, y = 2, 4
true, true, true, true, true이고, x < y 일 때, 사이의 방을부순다.
2번의 행동 모두 위의 조건을 만족하기 때문에 사이의 벽을 부순다.
첫번째 행동: true, false, true, true, true
두번째 행동: true, false, false, false, true
벽이 사라진다는 것은 x < 부숴지는 방 <= y 이다.

1. N만큼의 배열의 공간에 true로 방을 만든다.
2. 시작방과 끝방-1만큼 반복문을 순회하며 false로 방을 제거한다.
3. 남아있는 방의 개수를 카운트한다.

const filePath = process.platform === "linux" ? "/dev/stdin" : "./input.txt";
const input = require("fs").readFileSync(filePath).toString().trim().split("\n");

const N = Number(input.shift());
const M = Number(input.shift());

// true = 부숴지지 않은 벽, false = 부숴진 벽
const walls = Array.from({ length: N }).fill(true);

for (let i = 0; i < M; i++) {
  const [startRoom, endRoom] = input[i].split(" ").map(Number);

  for (let j = startRoom; j < endRoom; j++) {
    walls[j] = false;
  }
}

console.log(walls.filter((el) => el === true).length);