[프로그래머스] 지형 편집 / Java

2021. 4. 6. 15:53·Programmers
반응형

문제주소 :programmers.co.kr/learn/courses/30/lessons/12984

 

코딩테스트 연습 - 지형 편집

XX 게임에서는 지형 편집 기능을 이용하여 플레이어가 직접 게임 속 지형을 수정할 수 있습니다. 이 게임에서는 1 x 1 x 1 크기의 정육면체 블록을 쌓아 게임 속 지형을 표현합니다. 이때, 블록이

programmers.co.kr


<문제 설명>

더보기

문제 설명

XX 게임에서는 지형 편집 기능을 이용하여 플레이어가 직접 게임 속 지형을 수정할 수 있습니다. 이 게임에서는 1 x 1 x 1 크기의 정육면체 블록을 쌓아 게임 속 지형을 표현합니다. 이때, 블록이 공중에 떠 있거나, 블록 하나가 여러 개의 칸에 걸쳐 놓일 수는 없습니다. 따라서 지형을 편집하기 위해서는 각 칸의 제일 위에 블록 1개를 새로 추가하거나, 제일 위에 있는 블록 한 개를 삭제하는 방식으로 지형을 수정해야 합니다. 이때, 블록 한 개를 새로 추가하거나 삭제하기 위해서는 게임머니를 사용해야 하므로 몇 개의 블록을 추가하고 삭제할지 신중한 선택이 필요합니다.

이 게임을 즐기던 한 플레이어는 N x N 크기의 지역에 자신만의 별장을 만들고 싶어졌습니다. 이를 위해서는 울퉁불퉁한 지형의 모든 칸의 높이가 같아지도록 만들어야 합니다. 이때, 블록 한 개를 추가하려면 P의 비용이, 제거하려면 Q의 비용이 들게 됩니다.
다음은 블록 한 개를 추가할 때 5의 비용이, 제거할 때 3의 비용이 드는 경우, 3 x 3 넓이의 모든 칸의 블록 높이가 같아지도록 만드는 예시입니다.

위 그림과 같이 지형 블록이 놓여 있는 경우 모든 칸의 높이가 3으로 같아지도록 한다면 다음과 같은 모양이 됩니다.

이를 위해서는 3보다 높은 칸의 블록 2개를 제거하고, 3보다 낮은 칸에 총 8개의 블록을 추가해야 하며, 2 x 3 + 8 x 5 = 46의 비용이 들게 됩니다.

그러나 아래 그림과 같이 모든 칸의 높이가 2로 같아지도록 할 때는 6개의 블록을 제거하고, 3개의 블록을 추가하면 6 x 3 + 3 x 5 = 33의 비용이 들게 되며, 이때가 최소비용이 됩니다.

현재 지형의 상태를 나타내는 배열 land와 블록 한 개를 추가하는 데 필요한 비용 P, 블록 한 개를 제거하는 데 필요한 비용 Q가 매개변수로 주어질 때, 모든 칸에 쌓여있는 블록의 높이가 같아지도록 하는 데 필요한 비용의 최솟값을 return 하도록 solution 함수를 완성해 주세요.

제한사항

  • land는 N x N 크기의 2차원 배열이며, N의 범위는 1 ≤ N ≤ 300입니다.
  • land의 각 원소는 각 칸에 놓여 있는 블록의 수를 나타내며, 0 이상 10억 이하의 정수입니다.
  • 각 칸에 블록 하나를 추가하는 데는 P, 제거하는 데는 Q의 비용이 들며, P, Q의 범위는 1 ≤ P, Q ≤ 100인 자연수입니다.

입출력 예

land                               P                                   Q                                   result
[[1, 2], [2, 3]] 3 2 5
[[4, 4, 3], [3, 2, 2], [ 2, 1, 0 ]] 5 3 33

입출력 예 설명

입출력 예 #1

  • 모든 땅의 높이를 1로 맞추는 데는 블록 4개를 제거해야 하므로 8의 비용이 듭니다.
  • 모든 땅의 높이를 2로 맞추는 데는 블록 1개를 추가하고 블록 1개를 제거해야 하므로 5의 비용이 듭니다.
  • 모든 땅의 높이를 3으로 맞추는 데는 블록 4개를 추가해야 하므로 12의 비용이 듭니다.

따라서 최소 비용은 5이므로 5를 return 합니다.

입출력 예 #2
문제의 예시와 같으며 최소 비용은 33입니다.

 

<풀이법>

▒ 한줄 개념: 이분 탐색 ▒ 

이분탐색 알고리즘을 사용하여 푸는 문제이다. 아래 블로그를 참고했다.

comyoung.tistory.com/166

 

[프로그래머스] 지형 편집

문제) https://programmers.co.kr/learn/courses/30/lessons/12984 풀이) 이분 탐색을 활용해서 푼 문제이다. land 중 가장 적은 높이를 start, 가장 큰 높이를 end라고 할 때 비용을 계산해 볼 기준 높이 mid는..

comyoung.tistory.com

풀이방식은 다음과 같다.

 

1. 현재 지형 중 최소높이, 최대높이를 구한다. 이분탐색 범위인 start = 최소높이 / end = 최대높이가 된다.

2. 해당 범위내에서 이분탐색을 진행하는데, mid = (start+end) / 2 이다. mid, mid+1 을 가지고 각각의 비용을 구하고, mid > mid+1 일 경우 탐색 범위가 mid+1 ~ end가 된다. 반대로 mid < mid + 1 일 경우 탐색 범위가 start ~ mid가 된다.

 

주의사항으로, 모든 변수는 long으로 선언한다. 각 블록의 높이가 최대 10억이 가능하기 때문에, int로 하면 계산이 정확하지 않을 수 있다. 처음에 start, end, mid를 int로 선언해주었더니 효율성 1~5번이 틀렸다. int값이 담을 수 없는 값이 계산되면서 오류가 발생한 것 같다. 분명 int로 21억까지 가능할텐데.. 원인은 잘 모르겠지만 long으로 모든 변수를 선언해야 다 통과할 수 있다.

 

이분탐색이 개념은 굉장히 쉬운 알고리즘인데, +1, -1 하는 과정에서 한틱의 오류가 사람을 좀 괴롭게 만드는 것 같다. 추상적으로는 구현이 쉽지만, 한칸한칸 계산하는 것이 머릿속에서 오류를 좀 일으킨다. 이분탐색 문제를 좀 더 풀어봐야 할 것 같다.

 

<코드(Java)>

public class Solution {
        int[][] land;
        int P,Q;
        int N;
        
        public long solution(int[][] land, int P, int Q) {
            long answer = 0;
            
            this.land = land;
            this.P = P;
            this.Q = Q;
            this.N = land.length;
            
            long end = this.land[0][0]; 
            long start = this.land[0][0];
            for(int i = 0; i < this.N; i++){
                for(int j = 0; j < this.N; j++){
                    if(this.land[i][j] > end)
                        end = this.land[i][j];
                    if(this.land[i][j] < start)
                        start = this.land[i][j];
                }
            }
            
            long mid;
            while(start <= end){
                
                mid = (start + end)/ 2;
                
                long leftCost = calculateCost(mid);
                long rightCost = calculateCost(mid+1);
                
                if(leftCost > rightCost){
                    answer = rightCost;
                    start = mid+1;
                }
                else{
                    answer = leftCost;
                    end = mid-1;
                }
            }
            
            return answer;
        }
        
        long calculateCost(long height){
            long cost = 0;
            for(int i = 0; i < this.N; i++){
                for(int j = 0; j < this.N; j++){
                    if(land[i][j] > height){
                        cost += (land[i][j] - height) * Q; 
                    }
                    else{
                        cost += (height - land[i][j]) * P;
                    }
                }
            }
            return cost;
        }
    }

 

 

더 많은 코드 보기(GitHub) : github.com/dwkim-97/CodingTest

 

 

반응형
저작자표시 (새창열림)

'Programmers' 카테고리의 다른 글

[프로그래머스] 음양 더하기 / Java, JavaScript  (0) 2021.04.20
[프로그래머스] 리틀 프렌즈 사천성 / Java  (2) 2021.04.07
[프로그래머스] 쿠키 구입 / Java  (0) 2021.04.05
[프로그래머스] 지형 이동 / Java  (0) 2021.04.04
[프로그래머스] 동굴 탐험 / Java  (0) 2021.04.01
'Programmers' 카테고리의 다른 글
  • [프로그래머스] 음양 더하기 / Java, JavaScript
  • [프로그래머스] 리틀 프렌즈 사천성 / Java
  • [프로그래머스] 쿠키 구입 / Java
  • [프로그래머스] 지형 이동 / Java
개발하는 사막여우
개발하는 사막여우
개발개발 주저리주저리
    반응형
  • 개발하는 사막여우
    개발하는 사막여우
    개발하는 사막여우
  • 전체
    오늘
    어제
    • All (311)
      • Books (13)
        • 읽기 좋은 코드가 좋은 코드다 (13)
      • Study (6)
        • Blockchain (3)
        • Algorithm (3)
      • Baekjoon (36)
      • Programmers (166)
      • LeetCode (15)
      • Open Source (1)
        • Youtube Popout Player (1)
      • Language (32)
        • Python (9)
        • JS (8)
        • Java (5)
        • HTML (6)
        • CSS (4)
      • Library & Framework (15)
        • React.js (15)
      • IDE (2)
        • IntelliJ (2)
      • Airdrop (9)
      • Tistory (2)
      • etc.. (7)
        • Cozubi (6)
        • lol-chess (0)
  • 블로그 메뉴

    • Github
  • 링크

    • Github
  • 공지사항

  • 인기 글

  • 태그

    Cozubi
    프로그래머스
    프로그래머스 위클리 챌린지
    2018 KAKAO BLIND RECRUITMENT
    백준
    카카오 코딩테스트
    코주비
    읽기 좋은 코드가 좋은 코드다
    코딩테스트연습
    알고리즘문제풀이
    programmers
    클린 코드
    신규 코인 에어드랍
    Python
    카카오 공채
    카카오 알고리즘 문제
    Java
    코인줍줍
    파이썬
    클린 코드 작성법
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.6
개발하는 사막여우
[프로그래머스] 지형 편집 / Java
상단으로

티스토리툴바