[C#] 야근 지수

소슬잎·2023년 11월 13일

프로그래머스 문제

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

풀이 후기

1. 분석

나만 그런지 모르겠지만, 글을 좀 귀찮게 써놓은 것 같다. 배열 내의 n만큼 요소들의 값을 줄일 수 있고, 배열 내의 숫자를 제곱해서 더했을 때 최솟값을 찾으시오 정도로 쓸 수 있는 게 아닐까.

핵심은 9^2 = 81, 7^2 = 49이므로, 큰 숫자를 먼저 죽이면 된다. 최대 힙을 쓰던가, 그냥 정렬하든가 대충 아무거나. 다만 이 부분에서 살짝 까다로운 게 요소의 값을 변경하면 최댓값이 바뀌기 때문에 좋은 방법을 고안해야 하는 것.

2. 풀이

내가 생각한 방법은 정렬하고 '나와 다음 값의 차이' 만큼 값을 빼서 동등하게 만드는 방법. 그런데 이렇게 구현하면 10, [10, 10, 1] 같은 케이스를 실행할 때, n 숫자를 고려하지 않고 그냥 막 빼기 때문에 정답이 망한다.

다음 방법은 그냥 얌전히 1씩 빼는 방법. 나와 다음 숫자가 같으면 1을 빼고 다음 요소로 넘어가고, 다르면 1을 빼고 배열의 첫 번째 요소로 이동한다. 뭔가 산을 꼭대기부터 한 칸 씩 깎는 느낌이다. 1씩 뺀다는 것 자체가 효율성에서 문제가 생길 것 같긴 했는데 왜인지 다 통과했다.

3. 실행 결과

4. 코드

using System;
using System.Linq;

public class Solution {

    public long CalcWorksToResult(int[] works)
    {
        return works.Aggregate<int, long>(0, (current, t) => current + t * t);
    }
    
    public long solution(int n, int[] works) {
        long answer = 0;
        var orderWorks = works.OrderByDescending(i => i).ToArray();

        if (works.Length == 1)
        {
            var result = Math.Max(works[0] - n, 0);
            return result * result;
        }

        var index = 0;
        while (0 < n)
        {
            var a = orderWorks[index];
            var b = orderWorks[index + 1];

            if (a == b)
            {
                orderWorks[index] -= 1;
                n -= 1;
                index++;
            }
            else if (a > b)
            {
                orderWorks[index] -= 1;
                n -= 1;
                index = 0;
            }

            if (index == works.Length - 1)
            {
                var value = Math.Min(1, n);
                orderWorks[index] -= value;
                n -= value;
                index = 0;

                if (orderWorks[index] == 0)
                {
                    return 0;
                }
            }
        }

        return CalcWorksToResult(orderWorks);
    }
}

코드가 좀 더러워서 바꾸고 싶지만, 리포트를 써야 하므로...

profile
그냥 바보

0개의 댓글