[카카오] 이모티콘 할인행사 (Java)

SSO·2023년 9월 8일
0

알고리즘

목록 보기
48/48

🍇 문제

2023 KAKAO BLIND RECRUITMENT Lv2. 이모티콘 할인행사
https://school.programmers.co.kr/learn/courses/30/lessons/150368

이모티콘 플러스 가입자 수의 최댓값을 유지하면서 이모티콘 판매액을 최대로 할 때의 가입자 수와 판매액을 구하여라.
각 사용자들은 자신의 기준에 따라 일정 비율 이상 할인하는 이모티콘을 모두 구매한다. 자신의 기준에 따라 이모티콘 구매 비용의 합이 일정 가격 이상이 된다면, 이모티콘 구매를 모두 취소하고 이모티콘 플러스 서비스에 가입한다.
이모티콘마다 할인율은 다를 수 있으며, 할인율은 10%, 20%, 30%, 40% 중 하나로 설정된다.

  • int[][] users : 사용자의 구매 기준을 담은 배열
  • int[] emoticons: 이모티콘의 정가를 담은 배열

🍇 풀이

  1. 중복 조합을 사용하여 각 이모티콘의 할인 비율에 대한 모든 경우의 수를 구한다.
  2. 모든 경우의 할인이 적용된 이모티콘에 대하여 판매액을 구하고, 각 유저가 플러스에 가입하거나 이모티콘을 구매하는 총액을 구한다.
  3. 각 경우의 플러스 가입 수와 판매액을 가지고 가입 수를 최대로 하되, 그 중 판매액을 최대로 하는 값을 업데이트하여 구한다.

이모티콘 가격에 할인 비율을 적용하면서 double 타입을 잘못 썼다가 몇 가지 케이스에서 실패가 떴다. 신중하게 사용하도록 해야겠다. 또한 따져야 할 것이 많아 변수가 많이 나왔다. 헷갈리지 않게 변수명을 직관적으로 짓는 것이 중요한 것을 깨달았다. 이해만 잘하면 쉬운 문제!


🍇 전체 코드

import java.util.*;

class Solution { // 플러스 가입자 늘리기 -> 판매액 늘리기
    static int[] percent = {0, 10, 20, 30, 40};  // 할인율 10% 20% 30% 40%
    static int total_join = 0, total_price = 0, min = Integer.MAX_VALUE;
    
    public int[] solution(int[][] users, int[] emoticons) {
    	// 사용자가 구매할 이모티콘의 최소 할인 비율 구하기
        for (int[] user : users) {
            min = Math.min(min, user[0]); // 최소 할인 비율
        }
        for (int i = 0; i < 5; i++) {
            if (min <= percent[i]) {
                min = i; // index
                break;
            }
        }
        
        // 중복조합 돌리기
        int[] discounts = new int[emoticons.length];
        comb(discounts, 0, emoticons.length, users, emoticons);
        
        int[] answer = {total_join, total_price}; // 가입 유저 수, 매출액
        return answer;
    }
    
    private void comb(int[] discounts, int s, int n, int[][] users, int[] emoticons) {
        if (s == n) {
            cal(users, emoticons, discounts);
            return;
        }
        
        for (int i = s; i < n; i++) {
            for (int j = min; j < 5; j++) { // 최소 할인 비율부터
                discounts[i] = percent[j];
                comb(discounts, i + 1, n, users, emoticons);
            }
        }
    }
    
    private void cal(int[][] users, int[] emoticons, int[] discounts) {
        int join = 0; // 플러스 가입 수
        int price = 0; // 판매액
        
        for (int[] user : users) {
            int userMinDiscount = user[0];
            int userMaxPay = user[1];
            int sum = 0;
            
            for (int i = 0; i < discounts.length; i++) {
                if (discounts[i] < userMinDiscount) continue;
                sum += sale(emoticons[i], discounts[i]);
            }
            
            // 기준점 이상이면 가입, 아니면 구입
            if (userMaxPay <= sum) join++;
            else price += sum;
        }
        
        // static 변수 업데이트
        if (join > total_join) {
            total_join = join;
            total_price = price;
        } else if (join == total_join && price > total_price) {
            total_price = price;
        }
    }
    
    private int sale(int price, int percent) { // 할인 적용된 가격 구하기
        return (price / 100) * (100 - percent);
    }
}

🍇 Comment

  • 정수형만으로 할인 적용 금액을 계산하는 로직을 새롭게 알게 되었다.
  • 변수명을 직관적으로 짓자!
profile
쏘's 코딩·개발 일기장

0개의 댓글