문제
농부 존의 농장에 원형 길이 있다고 했지만, 길은 그뿐만이 아니다. 그 옆에 일자형 길이 있는데, 1번부터 N번까지의 번호가 붙은 횡단보도 N (1 ≤ N ≤ 100,000)개로 이루어져 있다. 교통사고를 방지하기 위해 존은 각 횡단보도에 신호등을 설치해 놓았다. 그러던 어느 날, 강력한 뇌우로 인해 몇몇 신호등이 망가졌다. 존은 연속한 K개의 신호등이 존재하도록 신호등을 수리하고 싶다. 이번에도 우리가 존을 도와주자.
입력
첫 줄에 N, K, B (1 ≤ B,K ≤ N)가 주어진다. 그 다음 B줄에는 고장난 신호등의 번호가 하나씩 주어진다.
출력
정상적으로 작동하는 연속 K개의 신호등이 존재하려면 최소 몇 개의 신호등을 수리해야 하는지 출력한다.
문제 풀이
슬라이딩 윈도우 문제.
1번부터 N번까지 신호등이 고장났는지 여부를 저장하는 boolean 타입 배열을 생성한다. 처음에는 1번부터 K번까지 고장난 신호등의 개수(= 수리해야 하는 신호등의 개수)를 정답을 나타내는 변수인 answer에 저장한다. 그 이후 N까지 윈도우를 한 칸씩 밀면서 그 상태의 윈도우에서 수리해야 하는 신호등의 개수를 구한다. 한 칸 밀어내므로 현재 윈도우의 맨 뒤 신호등이 i번이라고 하면 i-K번은 윈도우에서 벗어난다. 만약 i-K번 신호등이 고장났으면 이전 수리해야 하는 신호등의 개수에서 1이 빠지게 된다. 그리고 맨 뒤 신호등이 고장났다면 이전 수리해야 하는 신호등의 개수에서 1이 추가가 된다. 각 상태마다 최솟값과 비교하고 저장하며 최종 최솟값을 구해주면 된다.
아래는 코드.
#include <iostream>
using namespace std;
bool* isBroken;
int main()
{
cin.tie(NULL);
ios::sync_with_stdio(false);
int N, M, B, num;
cin >> N >> M >> B;
int answer = 0;
isBroken = new bool[N+1];
for (int i = 0; i < N+1; i++)
{
isBroken[i] = false;
}
for (int i = 0; i < B; i++)
{
cin >> num;
isBroken[num] = true;
}
for (int i = 1; i <= M; i++)
{
if (isBroken[i] == true)
{
answer++;
}
}
int tempAnswer = answer;
for (int i = M + 1; i <= N; i++)
{
if (isBroken[i - M] == true)
{
tempAnswer--;
}
if (isBroken[i] == true)
{
tempAnswer++;
}
answer = min(answer, tempAnswer);
}
cout << answer << "\n";
return 0;
}
'알고리즘 > 백준' 카테고리의 다른 글
[백준 22232] 가희와 파일 탐색기 (C++) (0) | 2024.10.29 |
---|---|
[백준 24416] 알고리즘 수업 - 피보나치 수 1 (C++) (0) | 2024.10.28 |
[백준 2303] 숫자 게임 (C++) (0) | 2024.10.25 |
[백준 27527] 배너 걸기 (C++) (0) | 2024.10.24 |
[백준 7432] 디스크 트리 (C++) (0) | 2024.10.23 |