💡문제 분석 요약

https://www.acmicpc.net/problem/1654

  • 길이가 제각각인 K개의 랜선을 모두 N개의 같은 길이의 랜선으로 만들려고 한다.
  • 이미 자른 랜선은 붙일 수 없다.
  • ex. 300cm 랜선에서 140cm 랜선을 두 개 잘라내면 20cm는 버려야 함
  • 기존의 K개의 랜선으로 N개의 랜선을 만들 수 없는 경우는 없음
  • 자를 때는 정수길이 단위
  • N개보다 많이 만든느 것도 N개를 만드는 것에 포함함
  • 만들 수 있는 최대 랜선의 길이 return

💡 K = 4 N = 11
802
743
457
539
최대 랜선의 길이가 200일 때
802cm 랜선에서 4개, 743cm 랜선에서 3개, 457cm 랜선에서 2개, 539cm 랜선에서 2개를 잘라내 모두 11개를 만들 수 있음

💡알고리즘 설계

  • 입력받은 랜선의 길이를 LAN 변수에 list로 저장 후 start = 1, end = min(LAN)
  • 해당 구간을 이진탐색 하며 LAN의 각 요소를 mid로 나눈 몫 확인
    • 몫의 합이 N의 값보다 크거나 같다면 start = mid + 1
    • N보다 작다면 end = mid - 1
  • end return

💡코드

import sys

def CUTLAN(n, lan) :
    start = 1
    end = max(lan)

    while start <= end :
        mid = (start + end) // 2
        sum = 0
        for l in lan :
            sum += l // mid
        if sum >= n : start = mid + 1
        else : end = mid - 1
    return end

if __name__ == '__main__' :
    k, n = map(int, sys.stdin.readline().split())
    lan = []
    for i in range(k) :
        lan.append(int(sys.stdin.readline()))
    print(CUTLAN(n, lan))

💡시간복잡도

  • 1부터 N까지 이진탐색하므로 O(logN)
  • 위 loop 안에서 LAN길이(M)만큼 for loop를 돌기 때문에 O(M)
  • 따라서 시간복잡도는 O(MlogN)

💡 틀린 이유

  • k = 3, n = 4, 10 10 1 로 입력이 들어왔을 때를 처리하지 못함

💡 틀린 부분 수정 / 다른 풀이

  • end의 값을 LAN의 min 값으로 해도 된다고 생각했는데 위의 경우 start = 1, end = 1이 되어 결과값이 예상했던 5가 아닌 1이 나온다.

💡 느낀점 / 기억할정보

  • end의 값을 반례를 생각하며 조금 더 꼼꼼하게 정하도록 하자
  • 마지막에 return end를 하는 이유는 while루프를 빠져나올 때 end의 값이 바뀌면서 나오기 때문인 것 같다.

0개의 댓글