[백준] 2805 나무 자르기 - 자바

2023. 8. 28. 21:53·Coding Test/백준

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

 

2805번: 나무 자르기

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

www.acmicpc.net

문제 풀이

이 문제도 입력 조건을 보면 범위가 상당히 크기 때문에 순차탐색이 아닌 이분탐색을 통해 아웃풋을 구해야 한다.

'M미터의 나무를 집에 가져가기 위해서 절단기에 설정할 수 있는 높이의 최댓값을 출력한다.' 즉 M미터를 가져가기 위한 절단기의 높이는 여러 개가 나올 수 있고 이 중 최댓값을 구해야 하므로 upper bound 이분 탐색을 적용한다.

 

코드

package 백준;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Arrays;
import java.util.StringTokenizer;

public class b2805 {
    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        StringTokenizer st = new StringTokenizer(br.readLine());

        int n = Integer.parseInt(st.nextToken());
        int m = Integer.parseInt(st.nextToken());
        int[] woods = Arrays.stream(br.readLine().split(" ")).mapToInt(Integer::parseInt).toArray();

        int left = 0;
        int right = Arrays.stream(woods).max().getAsInt();
        while (left < right) {
            int mid = (right + left) / 2;
//            long len = (long)Arrays.stream(woods).map(x -> x - mid).filter(x -> x > 0).sum();
            long len = 0;
            for (int wood : woods) {
                if (wood - mid > 0) {
                    len += wood - mid;
                }
            }

            if (len < m) {
                right = mid;
            } else {
                left = mid + 1;
            }
        }
        System.out.println(left-1);

    }
}

코드 풀이

몇 십분 동안 삽질한 코드이다.

//            long len = (long)Arrays.stream(woods).map(x -> x - mid).filter(x -> x > 0).sum();
long len = 0;
for (int wood : woods) {
    if (wood - mid > 0) {
        len += wood - mid;
    }
}

다음 코드는 작동 원리는 똑같다. 하지만 이 문제에선 값이 다르게 들어갈 때가 있다.

먼저 len은 나무 높이에 대해 자르고 남은 길이를 뜻한다. 나무 높이는 최대 10억까지 나올 수 있고 나무는 1백만 개 나올 수 있으므로 len은 long 타입이어야 한다. 위 스트림,람다 코드도 이를 인지하고 작성했지만 결과값 자체가 int형이기 때문에 아무리 형변환을 해줘도 이미 오버플로우가 발생한 값에 대해 형변환을 해주기 때문에 이상한 값을 반환한다.

 

이를 테스트 했던 코드이니 결과값만 확인해도 좋다.

int[] woods = Arrays.stream(br.readLine().split(" ")).mapToInt(Integer::parseInt).toArray();
int mid=0;
long len = Arrays.stream(woods).map(x -> x - mid).filter(x -> x > 0).sum();
long len2 = 0;
for (int wood : woods) {
    if (wood - mid > 0) {
        len2 += wood - mid;
    }
}

System.out.println("len2 = " + len2);
System.out.println("len = " + len);

'Coding Test > 백준' 카테고리의 다른 글

[백준] 11053 가장 긴 증가하는 부분 수열 - 자바  (0) 2023.08.29
[백준] 2110 공유기 설치 - 자바  (0) 2023.08.29
[백준] 1654 랜선 자르기 - 자바  (1) 2023.08.28
[백준] 1992 쿼드트리 - 자바  (0) 2023.08.28
[백준] 2560 색종이 만들기 - 자바  (0) 2023.08.27
'Coding Test/백준' 카테고리의 다른 글
  • [백준] 11053 가장 긴 증가하는 부분 수열 - 자바
  • [백준] 2110 공유기 설치 - 자바
  • [백준] 1654 랜선 자르기 - 자바
  • [백준] 1992 쿼드트리 - 자바
lsh2613
lsh2613
웹 백엔드 개발자 준비생의 공부일기
  • lsh2613
    Heon's Note
    lsh2613
  • 전체
    오늘
    어제
    • 분류 전체보기 (185)
      • Study (35)
        • Java (0)
        • Spring (14)
        • OOP (4)
        • JPA (12)
        • Design Pattern (3)
        • DB (0)
        • Http & Network (0)
        • Maven (0)
        • Gradle (0)
        • Jenkins (2)
      • DevOps (13)
      • Book Review (0)
        • 자바의 정석 (0)
      • Coding Test (117)
        • 이코테 (5)
        • 백준 (70)
        • 프로그래머스 (37)
        • SW Expert Academy (4)
      • Project (12)
        • WebSocket을 적용한 1:1 채팅 (0)
        • RabbitMQ(STOMP)를 적용한 1:1 채팅 (4)
        • MySQL Spatial Index를 적용한 성능.. (1)
        • Elasticsearch의 전문 검색 인덱스 성능.. (3)
      • Error Solution (6)
      • Review (0)
      • ETC (0)
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
    • 글쓰기
  • 링크

  • 공지사항

  • 인기 글

  • 태그

    rabbitmq
    채팅
    AMQP
    STOMP
    apic
  • 최근 댓글

  • hELLO· Designed By정상우.v4.10.0
lsh2613
[백준] 2805 나무 자르기 - 자바
상단으로

티스토리툴바