코딩테스트

[백준] 우당탕탕 영화예매 (JS)

여유로운 프론트엔드 개발자 2025. 5. 9. 20:49

문제

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

도은이는 동아리 문화의 날을 맞이하여 동아리원들과 함께 좌석이 M N열의 직사각형 모양으로 배치되어 있는 영화관에서 영화를 보기로 했다. 도은이는 동아리원의 유대감을 중요하게 생각하기 때문에 이미 예매가 완료된 좌석을 피해 동아리원들이 모두 가로로 이어서 앉을 수 있도록 자리를 예매하고 싶어 한다. 도은이를 도와 모든 동아리원들이 가로로 이어서 앉을 수 있도록 예매하는 경우의 수는 총 몇 가지가 있을지 구해보자. 단, 예매한 좌석은 동일하지만, 각 사람이 앉는 위치만 바뀌는 경우는 한 가지로 본다.

입력

첫째 줄에 영화관 세로줄의 개수 N(1≤N≤1000)과 가로줄의 개수 M(1≤M≤5000), 영화를 관람할 동아리원의 수 K(1≤K≤10)가 주어진다.

둘째 줄부터 N개의 줄에 걸쳐 그중 i번째 줄에는 i번째 열의 좌석 예매 현황이 길이 M인 문자열 si로 주어진다. si의 j번째 문자는 i열 j번째 좌석의 예매 현황을 나타내는데, 이 문자가 '0'이라면 예매 가능한 빈 좌석을, 이 문자가 '1'이라면 예매가 완료되어 예매가 불가능한 좌석을 나타낸다.

출력

동아리원들이 모두 가로로 이어서 앉을 수 있도록 영화를 예매하는 경우의 수를 출력한다. 단, 문제에서 주어진 조건에 맞게 영화를 예매할 수 있는 방법이 없다면 0을 출력한다.

풀이

1. 영화관의 각 가로줄(행)을 검사해야 하므로, 2차원 배열을 행 기준으로 순회한다.

2. 동아리원 모두가 가로로 나란히 앉을 수 있는 경우를 구해야 하므로, 연속된 K개의 좌석이 모두 비어 있는지 확인해야 한다.

3. 초기 슬라이딩 윈도우를 설정한 뒤, 그 구간의 합이 0인지 확인하고, 이후 윈도우를 한 칸씩 옮기며 계속해서 합이 0인지 검사한다.

4. 모든 행에 대해 이 과정을 반복하여 가능한 경우의 수를 구한 뒤, 최종 결과를 출력한다.

const fs = require("fs");
const input = fs.readFileSync("/dev/stdin").toString().trim().split("\n");

const [N, M, K] = input[0].split(" ").map(Number);
const seats = input.slice(1).map(line => line.split("").map(Number));

let answer = 0;
    
seats.forEach(seat => {
    let windowSum = 0;
    for (let i = 0; i < K; i++) {
        windowSum += seat[i];
    }
        
    if (windowSum === 0) answer++;
        
    for (let j = K; j < seat.length; j++) {
        windowSum = windowSum - seat[j - K] + seat[j];
        if (windowSum === 0) answer++;
    }
})

console.log(answer);

 

'코딩테스트' 카테고리의 다른 글

[백준] 줄줄이 박수 (JS)  (0) 2025.05.15
[백준] 문자열 교환 (JS)  (0) 2025.05.12
[백준] 수열 (JS)  (0) 2025.05.02
[백준] 귀여운 라이언 (JS)  (0) 2025.05.01
[백준] 소가 길을 건너간 이유 5 (JS)  (0) 2025.04.29