[Python] 백준/BOJ 20207번: 달력 (Gold 5)

2025. 10. 4. 01:11·Algorithm/백준 (BOJ)
반응형

💻 Problem

문제 보러 가기

 

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

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

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

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

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

이때 코팅지의 크기의 합은 3 x 8 + 2 x 2 = 28이다. 
일정의 개수와 각 일정의 시작날짜, 종료날짜가 주어질 때 수현이가 자르는 코팅지의 면적을 구해보자.

 

💡 Approach

연속된 일정의 기간(날짜) * 그 기간 중에 일정이 가장 많을 때의 일정 개수를 구하면 그게 하나의 코팅지 면적이다.

즉, 일정이 없을 때까지 며칠인지(너비)를 구하고 그 기간 중에 최대 일정 개수(높이)를 구하는 것을 반복하면 된다.

 

✏️ Solution

딕셔너리로 푸는 방법
import sys
from collections import defaultdict
input = sys.stdin.readline

N = int(input())
calendar = defaultdict(int)

for _ in range(N):
    S, E = map(int, input().split())

    for i in range(S, E + 1):
        calendar[i] += 1

w, h, area = 0, 0, 0
start = min(calendar.keys())
end = max(calendar.keys())

for day in range(start, end + 1):
    if calendar[day] != 0:
        w += 1
        h = max(h, calendar[day])

    if calendar[day] == 0 or day == end:
        area += w * h
        w, h = 0, 0

print(area)
리스트로 푸는 방법
import sys
from collections import defaultdict
input = sys.stdin.readline

N = int(input())
calendar = [0] * 367

for _ in range(N):
    S, E = map(int, input().split())

    for i in range(S, E + 1):
        calendar[i] += 1

w, h, area = 0, 0, 0

for day in range(1, len(calendar)):
    if calendar[day] != 0:
        w += 1
        h = max(h, calendar[day])

    else:
        area += w * h
        w, h = 0, 0

print(area)
반응형
'Algorithm/백준 (BOJ)' 카테고리의 다른 글
  • [Python] 백준/BOJ 17124번: 두 개의 배열 (Silver 3)
  • [Python] 백준/BOJ 5376번: 소수를 분수로 (Silver 1)
  • [Python] 백준/BOJ 18234번: 당근 훔쳐 먹기 (Gold 3)
  • [Python] 백준/BOJ 2597번: 줄자접기 (Silver 3)
올콩
올콩
콩 심은 데 콩 난다
  • 올콩
    콩스토리
    올콩
  • 전체
    오늘
    어제
    • 분류 전체보기 (206)
      • SSAFY (10)
      • Algorithm (120)
        • 이론 (6)
        • 백준 (BOJ) (112)
        • 프로그래머스 (1)
        • 코드트리 (1)
      • Trouble Shooting (10)
      • Frontend (7)
      • React (17)
      • Next.js (5)
      • Vue (4)
      • Node.js (2)
      • HTML (9)
      • DevOps (4)
        • Git (4)
      • Language (9)
        • JavaScript (0)
        • Java (9)
      • Embedded (1)
      • CS (5)
        • Network (1)
        • Blockchain (4)
      • 자격증 (2)
      • 기타 (1)
        • Tistory (1)
  • 블로그 메뉴

    • GitHub
    • 태그
    • 방명록
  • 링크

  • 공지사항

  • 인기 글

  • 태그

    bfs
    Java
    그리디
    수학
    Heap
    알고리즘
    강의
    구현
    백트래킹
    재귀
    중복순열
    블록체인
    SSAFYcial
    SSAFY
    Error
    Next.js
    React
    브루트포스
    DP
    티스토리챌린지
    dfs
    Algorithm
    싸피
    우선순위큐
    힙
    오블완
    html5
    백준
    파이썬
    순열
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.5
올콩
[Python] 백준/BOJ 20207번: 달력 (Gold 5)
상단으로

티스토리툴바