Algorithm/🔎 Problem Solving

[구현 / 초급] 20207 달력 (백준, Python, 실버1)

키깡 2022. 8. 7.
728x90

문제 출처

문제

수현이는 일년의 날짜가 1일부터 365일로 표시되어있는 달력을 가지고있다. 수현이는 너무나도 계획적인 사람이라 올 해 일정을 모두 계획해서 달력에 표시해놨다.

여름이 거의 끝나가자 장마가 시작되었고, 습기로 인해 달력에 표시한 일정이 지워지려고 한다. 지워지는 것을 막고자 수현이는 일정이 있는 곳에만 코팅지를 달력에 붙이려고 한다. 하지만 너무 귀찮았던 나머지, 다음과 같은 규칙을 따르기로 한다.

  • 연속된 두 일자에 각각 일정이 1개 이상 있다면 이를 일정이 연속되었다고 표현한다.
  • 연속된 모든 일정은 하나의 직사각형에 포함되어야 한다.
  • 연속된 일정을 모두 감싸는 가장 작은 직사각형의 크기만큼 코팅지를 오린다.

달력은 다음과 같은 규칙을 따른다.

  • 일정은 시작날짜와 종료날짜를 포함한다.
  • 시작일이 가장 앞선 일정부터 차례대로 채워진다.
  • 시작일이 같을 경우 일정의 기간이 긴 것이 먼저 채워진다.
  • 일정은 가능한 최 상단에 배치된다.
  • 일정 하나의 세로의 길이는 1이다.
  • 하루의 폭은 1이다.

위의 그림에서와 같이 일정이 주어졌다고 하자. 여기서 코팅지의 면적은 아래의 파란색 영역과 같다.

이때 코팅지의 크기의 합은 3 x 8 + 2 x 2 = 28이다.

일정의 개수와 각 일정의 시작날짜, 종료날짜가 주어질 때 수현이가 자르는 코팅지의 면적을 구해보자.

입력

첫째 줄에 일정의 개수 N이 주어진다. (1 ≤ N ≤ 1000)

둘째 줄부터 일정의 개수만큼 시작 날짜 S와 종료 날짜 E가 주어진다. (1 ≤ S ≤ E ≤ 365)

출력

코팅지의 면적을 출력한다.

예제 입력 1 복사

7
2 4
4 5
5 6
5 7
7 9
11 12
12 12

예제 출력 1 복사

28

예제 입력 2 복사

5
1 9
8 9
4 6
3 4
2 5

예제 출력 2 복사

36

풀이

1a820e79-e5fc-4e4a-b7ad-efe42cfd7cdd 
잉크 그리기
잉크 그리기
잉크 그리기
잉크 그리기
잉크 그리기
잉크 그리기
잉크 그리기
잉크 그리기
잉크 그리기
잉크 그리기
잉크 그리기
잉크 그리기
잉크 그리기
잉크 그리기
잉크 그리기
잉크 그리기
잉크 그리기
잉크 그리기
잉크 그리기
잉크 그리기
잉크 그리기
잉크 그리기
잉크 그리기
잉크 그리기
잉크 그리기
잉크 그리기
잉크 그리기
잉크 그리기
잉크 그리기
잉크 그리기
잉크 그리기
잉크 그리기
잉크 그리기
잉크 그리기
잉크 그리기
잉크 그리기
잉크 그리기
잉크 그리기
잉크 그리기
잉크 그리기
잉크 그리기
잉크 그리기
잉크 그리기
잉크 그리기
잉크 그리기
잉크 그리기
잉크 그리기
잉크 그리기
잉크 그리기
잉크 그리기
잉크 그리기
잉크 그리기
잉크 그리기
잉크 그리기
잉크 그리기
잉크 그리기
잉크 그리기
잉크 그리기
잉크 그리기
잉크 그리기
잉크 그리기
잉크 그리기
잉크 그리기
잉크 그리기
잉크 그리기

예제 그림에서 파악해보면, 연결되어 있는 일정은 무조건 1이상임.
따라서 아예 일정에 포함 안 될 때 일정이 끊긴 것이라고 파악할 수 있음.

  1. 0값을 가지는 1차원 배열 받아서 일정에 포함되는 시작일부터 끝일까지 모두 1을 더해준다.
  2. 이후, 1이상이면 연결된 일정이므로, 일정을 하루 더 추가 해주고 (열 추가) 해당 열이 가장 많은 일정을 가지는 일정인지 판별한다. (행 판별)
  3. 0이면 연결되지 않은 일정이므로 해당 지점에서 행*열로 넓이 구해주고, 행과 열 값을 초기화 해준다.
  4. 365일까지 도는 경우 해당 반복문에서는 정답에 더해지지 않음 => 반복문 끝나고 ans에 넓이값을 한번 더 더해준다.

문제 풀이

days = [0] * 366  # 365일 배열

import sys
input = sys.stdin.readline
N = int(input())

for _ in range(N):
  S, E = map(int, input().split())  # 시작일, 끝일 받아오기
  for se in range(S, E+1):
    days[se] += 1  #  일정있는 일에 1개씩 늘이기

row = 0
col = 0
ans = 0

for d in range(1, 366):
  if days[d]:
    row = max(row, days[d])
    col += 1
  else:
    ans += row * col
    row = 0
    col = 0
ans += row * col  # 365일에 해당하는 부분도 고려

print(ans)

댓글