[프로그래머스] 시험장 나누기 (2021 카카오 채용연계형 인턴십)

2025. 3. 21. 21:42·알고리즘 (PS)/Programmers
반응형

https://school.programmers.co.kr/learn/courses/30/lessons/81305#

 

프로그래머스

SW개발자를 위한 평가, 교육, 채용까지 Total Solution을 제공하는 개발자 성장을 위한 베이스캠프

programmers.co.kr

 

이진트리를 k개 그룹으로 분할할 때, 각 그룹에 있는 노드가 가진 가중치의 합의 최댓값이 최소가 되도록 하는 문제

최댓값이 최소가 되어야 한다는 점에서 이분탐색 (매개변수 탐색) 까지는 어렵지 않게 떠올릴 수 있었으나, 이진트리를 k개로 분할하는 구현에서 막혀서 어려웠다.

 

처음에는 각 트리에 대해서 누적합을 구하고, 누적합 정보를 기반으로 쪼개는 풀이를 떠올렸다.

하지만 이 풀이가 27점 맞고 틀려서 디버깅하다가 반례를 못찾아서 클로드에 물어봤더니 클로드는 정답 풀이를 잘 짜주었다. (무료버전)

GPT는 문제는 이해했으나 풀이를 내는데에는 실패했는데... 클로드가 이젠 더 똑똑해진 것 같다.

 

클로드의 풀이와 내 풀이를 비교하면서 클로드로부터 반례도 받았는데, GPT와 다르게 반례도 제대로 만들어줘서 도움을 많이 받았다.

내 풀이는 탑-다운으로 누적합 데이터를 이용해서 위에서부터 내려가면서 그룹을 나눴는데, 이렇게 나누니까 

 

      10

     / 

  10

  /

10

   \

    10

 

를 2개로 분할할 때 20이 아니라 30을 가능한 최댓값의 최소로 잡는 문제가 생겼다.

20을 기준으로 잡았을 때

루트 10 / 그 아래의 10 / 나머지 10 10 

이렇게 3개로 분할했기 때문이다.

 

위에서부터 내려오면 루트 기준 누적합이 40이므로 20보다 커서 쪼개기로 판단한다.

이 상태에서 일단 바로 쪼개버리기 때문에 벌써 오답이다.

그래서 쪼개는 판단은 최대한 미뤄서 나중에 판단해야 한다.

 

import sys
sys.setrecursionlimit(10 ** 5)


def solution(k, num, links):
    acc = [0 for _ in range(len(num))]

    def get_acc(i):
        if acc[i] > 0:
            return acc[i]
        if i == -1:
            return 0

        left, right = links[i]
        get_left, get_right = 0, 0
        if left != -1:
            get_left = get_acc(left)
        if right != -1:
            get_right = get_acc(right)

        acc[i] = num[i] + get_left + get_right
        return acc[i]

    #  트리의 루트 찾기
    root = -1
    s = sum(num)
    for i in range(len(num)):
        a = get_acc(i)
        if a == s:
            root = i

    def count_cuttings(node, limit):
        if node == -1:
            return 0, 0

        left, right = links[node]
        left_count, left_sum = count_cuttings(left, limit)
        right_count, right_sum = count_cuttings(right, limit)

        # 현재 서브트리 전체를 그룹으로 만들 수 있는 경우
        if num[node] + left_sum + right_sum <= limit:
            print(node, 0, num[node] + left_sum + right_sum)
            return right_count + left_count, num[node] + left_sum + right_sum

        # 좌/우 서브트리 중 하나만 그룹에 포함시킬 수 있는 경우
        # 더 작은 사이즈의 트리를 합쳐서 그룹에 넣고, 큰 그룹은 분리
        if num[node] + min(left_sum, right_sum) <= limit:
            return right_count + left_count + 1, num[node] + min(left_sum, right_sum)

        # 좌/우 서브트리 모두 그룹에 포함시킬 수 없는 경우
        return right_count + left_count + 2, num[node]


    def possible(v):
        count, _ = count_cuttings(root, v)
        return count < k

    start, end = max(num) - 1, s
    while start + 1 < end:
        mid = (start + end) // 2
        if possible(mid):
            end = mid
        else:
            start = mid

    answer = end
    return answer

 

프로그래머스 AI가 추천해줘서 풀어봤는데 알고보니 Lv.5 문제였다.

이 문제를 실제 시험에서 시간 내에 푼 사람이 있다니 대단하다는 생각이 들었다.

알고리즘도 열심히 해야겠다..

반응형
저작자표시 비영리 변경금지 (새창열림)

'알고리즘 (PS) > Programmers' 카테고리의 다른 글

[프로그래머스] 이중우선순위큐  (0) 2025.03.22
[프로그래머스] 길 찾기 게임 (2019 KAKAO BLIND RECRUITMENT)  (0) 2025.03.20
[프로그래머스] 도넛과 막대 그래프 (2024 KAKAO WINTER INTERNSHIP)  (0) 2024.11.22
[프로그래머스/python3] 다트 게임 (2018 KAKAO BLIND RECRUITMENT [1차])  (0) 2022.11.13
'알고리즘 (PS)/Programmers' 카테고리의 다른 글
  • [프로그래머스] 이중우선순위큐
  • [프로그래머스] 길 찾기 게임 (2019 KAKAO BLIND RECRUITMENT)
  • [프로그래머스] 도넛과 막대 그래프 (2024 KAKAO WINTER INTERNSHIP)
  • [프로그래머스/python3] 다트 게임 (2018 KAKAO BLIND RECRUITMENT [1차])
에버듀
에버듀
개발은 좋은데 뭘로 개발할까
  • 에버듀
    Blog. 에버듀
    에버듀
  • 전체
    오늘
    어제
    • 분류 전체보기 (614)
      • 개인 프로젝트 (43)
        • 토이 프로젝트 (3)
        • [2020] 카카오톡 봇 (9)
        • [2021] 코드악보 공유APP (22)
        • [2022] 유튜브 뮤직 클론코딩 (9)
        • [2025] 한글 SQL 데이터베이스 (0)
      • 팀 프로젝트 (22)
        • [2020] 인공지능 숫자야구 (4)
        • [2022] OSAM 온라인 해커톤 (10)
        • [2024] GDSC 프로젝트 트랙 (6)
        • [2025] 큰소리 웹 페이지 (2)
      • CS (335)
        • 자료구조 (19)
        • 어셈블리 (41)
        • 멀티미디어응용수학 (7)
        • 컴퓨터 구조 (29)
        • 알고리즘 분석 (4)
        • 컴퓨터 네트워크 (38)
        • 프로그래밍언어론 (15)
        • HCI 윈도우즈프로그래밍 (26)
        • 기초데이터베이스 (29)
        • 운영체제 (23)
        • 오토마타 (24)
        • 문제해결기법 (11)
        • 블록체인 (22)
        • 소프트웨어공학 (21)
        • 기계학습심화 (12)
        • 컴퓨터그래픽스와 메타버스 (8)
        • 분산시스템특론 (6)
      • 자기계발 (44)
        • 생각 정리 (22)
        • 대외활동 (11)
        • 동아리 (7)
        • 자격증 (3)
        • 머니 스터디 (1)
      • 알고리즘 (PS) (107)
        • BOJ (101)
        • Programmers (5)
        • 알고리즘 이모저모 (1)
      • WEB(BE) (8)
        • express.js (1)
        • Spring & Spring Boot (7)
      • WEB(FE) (2)
        • html, css, js (1)
        • React.js (1)
      • Tool & Language (6)
        • Edit Plus (1)
        • Git (1)
        • Python3 (2)
        • Java (2)
      • Infra (12)
        • AWS (1)
        • Oracle Cloud (8)
        • Firebase (2)
        • Network (1)
      • Android (18)
        • Java (6)
        • Flutter (12)
      • Window (2)
        • Visual Studio 없이 WPF (1)
        • MFC (1)
      • 독서 (14)
        • Inside Javascript (7)
        • Database Internals (6)
        • 한 글 후기 (1)
  • 링크

    • github
    • website
  • 인기 글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.6
에버듀
[프로그래머스] 시험장 나누기 (2021 카카오 채용연계형 인턴십)
상단으로

티스토리툴바