주녘공부일지

[프로그래머스 C#] Lv.4 지형 편집 본문

Programmers - C#/CodingTest Lv.4

[프로그래머스 C#] Lv.4 지형 편집

주녘 2024. 2. 1. 16:41
728x90

https://school.programmers.co.kr/learn/courses/30/lessons/12984

 

프로그래머스

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

programmers.co.kr

1. 정답코드 및 핵심 아이디어, 유의사항

주어진 2차원 영역의 층을 같은 높이로 맞추는 데에 드는 최소 비용을 구하는 문제

- 같은 높이로 맞추기 위해 가능한 건, 층을 추가하거나 삭제하는 것 뿐 (이동X)

 -> 층을 추가하는 비용과 삭제하는 비용은 따로 주어짐

 

중복 연산 최적화 아이디어

- 주어진 2차원 배열을 리스트에 저장해 오름차순으로 정렬 ( 계단 형태가 됨 )

- 정렬된 리스트를 0번 인덱스부터 순회해 가장 낮은 층부터 높은 층의 방향으로 만들어나감

- 현재 만들려는 층에 대한 연산은 이전에 만들었던 층의 결과에 추가, 삭제해 중복 연산을 최소화

 -> 이전 층보다 높아지면서 제거했던 블록을 복구해야 함 (제거한 비용을 돌려받기)

 -> 이전 층보다 높아지면서 층을 맞추기 위해 블록을 추가해야 함

 ( 위 두개의 연산의 제거하거나 추가하는 영역은 무조건 직사각형 영역이 됨 )

 

+ 주어진 문제의 특성 상 만들려는 층에 따른 비용 그래프는 2차원 그래프 형태를 띄므로 가장 낮은 층에서부터 높은 층으로 탐색을 이어갈 때 최소 비용이 갱신이 되지 않는다면, 층에 따라 탐색되는 비용은 점점 높아지므로 탐색할 필요가 없음

 

+ 층의 높이의 최대 값은 10억으로 int 자료형의 범위를 벗어나기 쉬우므로 long 자료형으로 연산하게 되는데, 형 변환이 되지 않아 값이 잘못되는 경우를 유의해야 함

 

주석 참조

    using System;
    using System.Collections.Generic;
    using System.Linq;

    public class Solution
    {
        public long solution(int[,] land, int p, int q)
        {
            long minCost, currCost; // 최소비용. 현재비용
            var list = new List<int>(); // 각 칸의 블록 개수 (층 개수)

            foreach (int i in land)
                list.Add(i);

            list.Sort(); // 오름차순 정렬

            // 가장 낮은 층으로 만드는 비용 (가장 낮은 층을 기준으로 모든 층 제거)
            long subNum = (long)list[0] * list.Count;
            currCost = (list.Sum(x => (long)x) - subNum) * q;
            minCost = currCost;

            for (int i = 1; i < list.Count; i++)
            {
                // 같은 층에 대해 다루게 되므로 pass
                if (list[i - 1] == list[i])
                    continue;

                long addFloor = list[i] - list[i - 1]; ; // 층 증가 수

                // 만들려는 층이 변경됨에 따라 제거했던 층을 취소
                currCost -= addFloor * (list.Count - i) * q;

                // 만들려는 층이 변경됨에 따라 추가되는 층을 추가
                currCost += addFloor * i * p;
                
                // 최소 비용이 갱신되지 않는다면
                if (minCost < currCost)
                    break;

                minCost = currCost;
            }

            return minCost;
        }
    }
728x90