오늘 풀어본 문제는 BOJ 20207 달력 이다~! 실버 1단계의 구현 문제를 풀어보았다.
수현이는 일년의 날짜가 1일부터 365일로 표시되어있는 달력을 가지고있다. 수현이는 너무나도 계획적인 사람이라 올 해 일정을 모두 계획해서 달력에 표시해놨다.
여름이 거의 끝나가자 장마가 시작되었고, 습기로 인해 달력에 표시한 일정이 지워지려고 한다. 지워지는 것을 막고자 수현이는 일정이 있는 곳에만 코팅지를 달력에 붙이려고 한다. 하지만 너무 귀찮았던 나머지, 다음과 같은 규칙을 따르기로 한다.
달력은 다음과 같은 규칙을 따른다.
위의 그림에서와 같이 일정이 주어졌다고 하자. 여기서 코팅지의 면적은 아래의 파란색 영역과 같다.
이때 코팅지의 크기의 합은 3 x 8 + 2 x 2 = 28이다.
일정의 개수와 각 일정의 시작날짜, 종료날짜가 주어질 때 수현이가 자르는 코팅지의 면적을 구해보자.
[입력]
첫째 줄에 일정의 개수 N이 주어진다. (1 ≤ N ≤ 1000)
둘째 줄부터 일정의 개수만큼 시작 날짜 S와 종료 날짜 E가 주어진다. (1 ≤ S ≤ E ≤ 365)
[출력]
코팅지의 면적을 출력한다.
주어진 조건대로 구현만 하면 되는 문제이다. 처음엔 어떤 자료구조를 써야 하나,, 2차원 배열도 고민했지만 사실상 그날 그날 주어진 일정의 갯수만 체크하면 되는 문제였다.
주어지는 입력대로 시작일(S) 부터 종료일(T) 까지 할일 갯수를 배열 task
에 올려준다. 입력이 끝나면 task
배열을 순회하면서 시작일, 종료일을 확인하고 해당 구간 내에서 가장 많은 할일의 갯수를 구해 코팅지의 면적을 더해주면 된다.
#include <iostream>
#include <vector>
//boj 20207 달력, 구현, 실버 1
using namespace std;
int main(){
ios_base::sync_with_stdio(false);
cin.tie(NULL);
cout.tie(NULL);
int answer = 0;
int N, S, E;
cin>>N;
vector<int> task(367, 0);
for (int i = 0; i < N; ++i) {
cin>>S>>E;
for (int j =S; j <=E; ++j) task[j]++;
}
int from = -1, to = -1, height = 0; // 시작일, 종료일, 최대 할일 갯수
for (int i = 1; i <=366 ; ++i) {
if (task[i]>0 && task[i-1]==0) from = i;
if (height<task[i]) height = task[i];
if (task[i-1]>0 && task[i]==0) {
to = i-1;
answer += (to-from+1)*height;
height = 0;
}
}
cout<<answer;
return 0;
}