[백준] 2805 나무 자르기(C#)

2024. 2. 1. 23:58· 동식이 취업시키기 작전/코딩테스트
목차
  1. 문제
  2. 코드
  3. 고민
728x90

문제

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

 

2805번: 나무 자르기

첫째 줄에 나무의 수 N과 상근이가 집으로 가져가려고 하는 나무의 길이 M이 주어진다. (1 ≤ N ≤ 1,000,000, 1 ≤ M ≤ 2,000,000,000) 둘째 줄에는 나무의 높이가 주어진다. 나무의 높이의 합은 항상 M보

www.acmicpc.net

코드

using System;
using System.Text;
using System.Collections.Generic;

namespace dongsik
{
    class Algorithm
    {
        static void Main(string[] str)
        {
            int[] input = Array.ConvertAll(Console.ReadLine().Split(' '), int.Parse);
            int n = input[0];
            int m = input[1];

            int[] tree = Array.ConvertAll(Console.ReadLine().Split(' '), int.Parse);

            long end = 0;
            long start = 0;
            
            foreach(int t in tree)
            {
                if(end < t) { end = t; }
            }

            while(start <= end)
            {
                long mid = (start + end)/2;
                long sum = 0;

                for(int i = 0; i < n; i++)
                {
                    if(tree[i] > mid)
                    {
                        sum += tree[i] - mid;
                    }
                }

                if(sum >= m) { start = mid + 1; }
                else { end = mid - 1; }
            }
            
            // 길이
            Console.Write(end);
        }
    }
}

고민

노션에 이런 고민들을 해봤다.. 그리고 계속해서 정답이 틀렸는데, 이유가

 

1. return은 mid가 아니라 end다.

2. long타입으로 선언

 

왜 end인지는 뤼튼이 알려줬다.

어머! 얘. 내가 알려줄게 너가 말하려던게 이거 맞지? 이건 말이야~~ 백준 2805 문제는 이진 탐색을 활용하여 풀 수 있는 문제야. 코드를 보니 대체적으로 잘 작성한 것 같아. 하지만 한 가지 문제가 있어. 문제는 이진 탐색이 끝나고 난 후의 결과 출력 부분이야. `Console.Write(mid);`라고 써서 마지막으로 계산한 mid 값을 출력하도록 했는데, 실제로는 mid 값이 아니라 end 값을 출력해야 해. 왜냐하면 이진 탐색의 과정에서 mid 값을 사용해 나무의 높이를 계산하고, 그 결과가 필요한 나무의 길이보다 크거나 같으면 시작점을 mid+1로 옮기는 과정을 거치잖아? 그런데 만약 필요한 나무의 길이와 정확히 일치하는 높이를 찾지 못하고, 그보다 조금 더 많이 잘랐을 경우에는 mid 값이 실제로 사용 가능한 최대 높이보다 1이 더 큰 상태로 종료되게 돼. 그래서 맞는 값을 출력하려면 `Console.Write(end);`로 바꿔야 해. 그러면 이진 탐색이 끝났을 때의 최대 높이를 올바르게 출력할 수 있을거야.

음.. 그렇다면 while문에 조건을 넣는다면?

 

            while(start <= end)
            {
                long mid = (start + end)/2;
                long sum = 0;

                for(int i = 0; i < n; i++)
                {
                    if(tree[i] > mid)
                    {
                        sum += tree[i] - mid;
                    }
                }
                
                if(mid == m) { result = mid; break; }

                if(sum >= m) { start = mid + 1; }
                else { end = mid - 1; }
            }
            
            // 길이
            Console.Write(result);

mid는 정답이 될 수 없는 것인지 고민하다가 위처럼 코드를 짰다. 하지만 실패

문제는 if(mid == m) { result = mid; break; } 이 부분이야. 이 코드는 이진 탐색의 중간 값(mid)이 목표로 하는 나무의 길이(m)과 같을 경우, 즉시 이진 탐색을 종료하도록 설계되어 있어.

하지만 이렇게 하면 문제가 생겨. 이 문제에서 나무의 길이와 중간값이 같다는 것이 곧 최적의 해라는 것을 보장하지 않아. 왜냐하면 mid 값이 m과 같더라도, 더 큰 mid 값에서도 m 이상의 나무를 얻을 수 있을지도 모르니까. 따라서 mid 값이 m과 같을 때 바로 종료하면 그보다 높은 높이에서 얻을 수 있는 결과를 놓칠 수 있어.

그렇다고 하네요... 

 

이진탐색을 무조건 mid에만 포커스를 두었는데, 실제로는 end였다니.. 너무 충격적이라서 기억에 오래 갈 거 같다.

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

'동식이 취업시키기 작전 > 코딩테스트' 카테고리의 다른 글

[백준] 10815 숫자카트(C#)  (0) 2024.02.04
[백준] 1654 랜선 자르기(C#)  (1) 2024.02.02
[백준] 1920 수 찾기(C#)  (0) 2024.01.31
[백준] 2309번 일곱 난쟁이  (1) 2024.01.30
[백준] 1436 영화감독 숌(C#)  (1) 2024.01.29
  1. 문제
  2. 코드
  3. 고민
'동식이 취업시키기 작전/코딩테스트' 카테고리의 다른 글
  • [백준] 10815 숫자카트(C#)
  • [백준] 1654 랜선 자르기(C#)
  • [백준] 1920 수 찾기(C#)
  • [백준] 2309번 일곱 난쟁이
이동식이
이동식이
개발자가 되고싶은 동식이... 티스토리를 시작하게 되었다.
동식이의 공부상자개발자가 되고싶은 동식이... 티스토리를 시작하게 되었다.
이동식이
동식이의 공부상자
이동식이
전체
오늘
어제
  • 분류 전체보기 (116)
    • 동식이 취업시키기 작전 (74)
      • 코딩테스트 (43)
      • 알고리즘 (5)
      • Unity (7)
      • CS (1)
      • 1차 프로젝트 : Overcooked2 (4)
      • FPS - Penguin party(feat. u.. (4)
      • UNITY로 FPS GAME 개발(FEAT. 1인.. (3)
      • 기업프로젝트 : Hacsamo (3)
    • 알고리즘 (15)
      • 백준 (4)
      • 프로그래머스 (10)
    • 일기 (3)
      • 회고 (0)
      • 리뷰 (0)
    • 자격증 (7)
      • 실기 (3)
      • 1. 요구사항 확인 (4)
    • Project (11)
      • Team Project (4)
      • Personal Project (0)
      • 베어머더러 (0)
      • 빵빵빵 타이쿤 (7)
    • 기술 블로그 염탐 (1)

블로그 메뉴

  • 홈
  • 태그
  • 방명록
  • 글쓰기
  • 관리자

공지사항

인기 글

태그

  • 프로그래머스
  • 무한배경
  • 슬픈 런타임에러 증후군
  • 배경스크롤링
  • 빵빵빵타이쿤
  • 유니티
  • 백준
  • system.action`1[t] callback) [0x00000] in <00000000000000000000000000000000>:0 at googleplaygames.ourutils.playgameshelperobject.update () [0x00000] in <00000000000000000000000000000000>:0 googleplaygames.ourutils.playgameshelperobject:update()
  • 파이썬
  • 개인정보수집유효기간
  • Photon
  • Python
  • [play games plugin 0.10.14] 06-11-25 23:27:52 +09:00 error: server auth code and id token require web clientid to configured. googleplaygames.ourutils.playgameshelperobject:update() [play games plugin 0.10.14] 06-11-25 23:27:52 +09:00 error: exception l
  • 애인에겐 머리를 조아려 감사함
  • Unity
  • 아자아자 파이팅이닷!
  • c#
  • 자료구조
  • 스택
  • 코딩테스트

최근 댓글

최근 글

hELLO · Designed By 정상우.v4.2.0
이동식이
[백준] 2805 나무 자르기(C#)
상단으로

티스토리툴바

개인정보

  • 티스토리 홈
  • 포럼
  • 로그인

단축키

내 블로그

내 블로그 - 관리자 홈 전환
Q
Q
새 글 쓰기
W
W

블로그 게시글

글 수정 (권한 있는 경우)
E
E
댓글 영역으로 이동
C
C

모든 영역

이 페이지의 URL 복사
S
S
맨 위로 이동
T
T
티스토리 홈 이동
H
H
단축키 안내
Shift + /
⇧ + /

* 단축키는 한글/영문 대소문자로 이용 가능하며, 티스토리 기본 도메인에서만 동작합니다.