[Python] 백준 1655 가운데를 말해요

2022. 8. 3. 15:34·CS/알고리즘 & 문제풀이

문제 링크 : https://www.acmicpc.net/problem/1655

 

1655번: 가운데를 말해요

첫째 줄에는 백준이가 외치는 정수의 개수 N이 주어진다. N은 1보다 크거나 같고, 100,000보다 작거나 같은 자연수이다. 그 다음 N줄에 걸쳐서 백준이가 외치는 정수가 차례대로 주어진다. 정수는 -1

www.acmicpc.net

 

1. 접근 방법

입력을 계속 받으며 중간 값을 출력해야 한다. 이때, 입력이 많기 때문에 계속 정렬을 한다거나 탐색을 하면 시간 초과가 날 것으로 보인다.

그렇기 때문에 중간값을 기준으로 큰 값, 작은 값을 각각 보관하고, 입출력이 많을 수 있기 때문에 heap 구조를 활용했다.


2. 풀이 코드

🖥python 코드 링크 : https://github.com/mintropy/PS/blob/master/BAEKJOON/Python/1000/1600/1655.py

 

GitHub - mintropy/PS: 다양한 알고리즘 문제 풀이 저장소입니다.

다양한 알고리즘 문제 풀이 저장소입니다. Contribute to mintropy/PS development by creating an account on GitHub.

github.com

📕코드 해설

처음 입력값은 중간 값으로, 그다음부터 입력값은 규칙에 따라 실행한다. 다음과 같은 순서로 진행한다.

위에서 mid에 배정된 값은 중간값, 왼쪽 오른쪽 부분은 각각 중간값보다 작은 값과 큰 값들이다. 이 그림에서는 선형적으로 기록했지만, 실제로는 heap구조에 기록된다.

우선 입력을 받으면 mid값보다 큰지 작은지 확인한 후 각 조건에 맞는 heap에 저장한다. 그리고 mid값이 중간값 조건, 만약 중간값이 2개(총개수가 짝수개)라면 더 작은 값을 출력하기 위해 큰 숫자를 보관하는 heap 크기가 작은 값을 보관하는 heap과 크기가 같거나 1개 더 저장하는 방식을 선택했다.

(아래 코드 설명 부분에서는 각 변수 small_val, large_val로 작성하겠다.)

 

if i % 2:
    if k < mid:
        heappush(large_val, mid)
        mid = -heappushpop(small_val, -k)
    else:
        heappush(large_val, k)
else:
    if k > mid:
        heappush(small_val, -mid)
        mid = heappushpop(large_val, k)
    else:
        heappush(small_val, -k)

코드로는 다음과 같이 구현된다.

우선 i가 홀수, 짝수인지에 따라 구분되는데, 이는 전체 숫자 갯수가 짝수, 홀수가 될 때를 의미한다.

만약 3번째 값인 2가 입력될 때를 생각해보자, 그렇다면 small_val에는 개 값이, large_val에는 2개 값이 저장되게 되는데,  그렇게 되면 mid값이 중간값이 될 수 없다. 그래서 지금 mid 값을 small_val에 추가, 새로운 입력을 large_val에 넣으면서 large_val의 최솟값을 mid값으로 지정한다. (첫 if-else 구분에서 else, 다음 if조건에 성립하는 경우)

다음으로 4번째 값인 10이 들어올때는 small_val, large_val 모두 1개 값을 가지고, mid값보다 더 큰 값이 입력되므로 large_val에 추가한다. (첫 if문을 만족, 두 번째 if문을 만족하지 않는 경우)

 


3. 생각 정리

heap구조는 최대, 최소값을 구하고 활용할 때 많이 사용했지만, 이번 문제처럼 여러 개의 heap구조를 상황에 나누어 활용하는 문제는 많이 접해보지 않아 처음 접근할 때 많은 고민을 했다. 그리고 python-heapq는 최소 heap으로만 동작하여 small_val에는 -1을 곱한 값으로 넣는 등의 동작도 고려해야 했다.

'CS > 알고리즘 & 문제풀이' 카테고리의 다른 글

[알고리즘] Segment Tree, lazy propagation  (0) 2022.08.19
[Python] 백준 13258 복권 + 은행  (0) 2022.08.05
[Python] 백준 20149 선분교차 3  (0) 2022.07.25
[Python] 백준 5527 일루미네이션  (0) 2022.07.11
[알고리즘] 이분 매칭(Bipartite Matching)  (0) 2022.05.22
'CS/알고리즘 & 문제풀이' 카테고리의 다른 글
  • [알고리즘] Segment Tree, lazy propagation
  • [Python] 백준 13258 복권 + 은행
  • [Python] 백준 20149 선분교차 3
  • [Python] 백준 5527 일루미네이션
mintropy
mintropy
민트로피의 하루하루 오늘보다 더 나은 내일
  • mintropy
    민트로피의 민트초코
    mintropy
  • 전체
    오늘
    어제
    • 분류 전체보기
      • 생각 정리
        • 코딩테스트
        • SSAFY
      • 디지털 노트
        • Obsidian.md
        • Notion
      • CS
        • 알고리즘 & 문제풀이
        • AI
        • DB
        • 디자인패턴
      • Projects
      • Python
        • Python Web Framework
      • JavaScript
        • React.js
      • Docker
  • 블로그 메뉴

    • 홈
    • 태그
  • 링크

  • 공지사항

  • 인기 글

  • 태그

    구현
    Python
    union-find
    브루트포스
    line
    SSAFY
    파이썬
    DP
    알고리즘
    그리디
    fastapi
    DRF
    Combinatorics
    ps
    django
    pydantic
    trie
    백준
    조건분기
    web framework
    프로그래머스
    회고
    bfs
    게임이론
    코딩테스트
    project_zero
    프로젝트
    dfs
    카카오
    markdown
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.6
mintropy
[Python] 백준 1655 가운데를 말해요
상단으로

티스토리툴바