문제
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 |