[프로그래머스] 시험장 나누기 (이분탐색)

2023. 8. 16. 12:46·Coding Test/programmers
728x90

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

 

프로그래머스

코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.

programmers.co.kr

 

분석

 

인원이 가장 많은 그룹의 인원이 최소화되도록 k개의 그룹으로 나누었을 때, 최소화된 최대 그룹의 인원을 return

➔ 한 그룹당 몇명으로 잡아야 k개의 그룹으로 나눴을때 최대 인원인지 구하기

  • 최대 노드 수: 10000개
  • 그룹을 최대 몇 개까지 나눌 수 있는지: 10000개
  • 완전 탐색 시: 조합(10000!) * 탐색(10000^2) ➔ 이분탐색

 

  • k : 그룹의 수를 나타내는 정수
  • num : 각 시험장의 응시자 수를 나타내는 1차원 정수 배열
  • links : 시험장의 연결 상태를 나타내는 2차원 정수 배열 
k : 3
num : [12, 30, 1, 8, 8, 6, 20, 7, 5, 10, 4, 1],
links : [[-1, -1], [-1, -1], [-1, -1], [-1, -1], [8, 5], [2, 10], [3, 0], [6, 1], [11, -1], [7, 4], [-1, -1], [-1, -1]]


start end limit (mid) 그룹 수
30 112 71 3
30 71 50 3
30 50 40 3
30 40 35 4
36 40 38 4
39 40 39 4
40 40    

answer = 40

 

 

풀이

import sys
sys.setrecursionlimit(10**6)

answer = 0

def solution(k, num, links):
    
    n = len(num)
    
    l = [0]*n
    r = [0]*n
    x = [0]*n
    
    parent=[-1]*n
    root=0
    
    for i in range(len(links)):
        x[i] = num[i]
        l[i], r[i] = links[i]
        if l[i] != -1: parent[l[i]] = i
        if r[i] != -1: parent[r[i]] = i

    for i in range(n): #  루트노드 찾기
        if parent[i]==-1:
            root=i; break
           
        
    def DFS(curr, limit):
        global answer
        left = right = 0
        if l[curr] != -1: left = DFS(l[curr], limit)
        if r[curr] != -1: right = DFS(r[curr], limit)

        # CASE 1: 모두 포함되는 경우
        if x[curr] + left + right <= limit:
            return x[curr] + left + right

        # CASE 2: limit보다 커서 한쪽 그룹을 자르는 경우
        if x[curr] + min(left, right) <= limit:
            answer += 1
            return x[curr] + min(left, right)

        # CASE 3: limit보다 커서 두쪽 그룹을 자르는 경우
        answer += 2
        return x[curr]

    
    def count(limit):
        global answer
        answer = 0
        DFS(root, limit)
        answer += 1
        return answer

    # 이분탐색
    start = max(x)
    end = sum(x)
    while start < end:
        mid = (start+end)//2
        if count(mid)<=k: # mid 명일 때
            end=mid
        else: 
            start=mid+1
        
    return start

 

 

 

728x90
저작자표시 비영리 변경금지 (새창열림)
'Coding Test/programmers' 카테고리의 다른 글
  • [프로그래머스] 공 이동 시뮬레이션
  • [프로그래머스] 고고학 최고의 발견
  • [프로그래머스] 코딩 테스트 공부 (DP, 다익스트라)
  • [프로그래머스] 2차원 동전 뒤집기
Karla Ko
Karla Ko
𝘾𝙤𝙣𝙩𝙞𝙣𝙪𝙤𝙪𝙨𝙡𝙮 𝙄𝙢𝙥𝙧𝙤𝙫𝙞𝙣𝙜, 𝘾𝙤𝙣𝙨𝙩𝙖𝙣𝙩𝙡𝙮 𝘿𝙚𝙫𝙚𝙡𝙤𝙥𝙞𝙣𝙜 𝙔𝙚𝙨!
    250x250
  • Karla Ko
    karlaLog
    Karla Ko
  • 전체
    오늘
    어제
    • Total (467)
      • Spring (19)
      • JPA (4)
      • Cloud & Architecture (15)
        • Kubernetes (5)
        • Docker (3)
        • MSA (2)
        • GCP (1)
        • AWS (4)
      • Devops (1)
      • Message Queue (4)
        • Kafka (2)
        • RabbitMQ (2)
      • Git (4)
      • DB (4)
      • Java (9)
      • Python (4)
      • CS (11)
        • OS (8)
        • Network (2)
        • Algorithm (1)
      • Coding Test (392)
        • programmers (156)
        • Graph (43)
        • DP (37)
        • Search (31)
        • Tree (13)
        • Data Structure (26)
        • Combination (12)
        • Implement (18)
        • Geedy (23)
        • Sort (7)
        • Math (21)
        • geometry (2)
  • 블로그 메뉴

    • 홈
  • 링크

  • 공지사항

  • 인기 글

  • 태그

    구간합
    파이썬
    구현
    다익스트라
    최단거리
    그래프
    트리
    백준
    정렬
    알고리즘
    이분탐색
    최소신장트리
    BFS
    플로이드워셜
    DP
    자료구조
    큐
    동적계획법
    월간코드챌린지
    프로그래머스
    스택
    최대공약수
    재귀
    Algorithm
    힙
    덱
    LIS
    그리디
    조합
    DFS
  • hELLO· Designed By정상우.v4.10.3
Karla Ko
[프로그래머스] 시험장 나누기 (이분탐색)
상단으로

티스토리툴바