ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • BOJ) 피자
    알고리즘/백준 2020. 6. 11. 17:15
    반응형

    피자

     

    3213번: 피자

    문제 오늘은 상근이의 생일이다. 상근이는 친구들과 피자를 먹으러 갔다. 상근이의 친구들은 매우 어려서 피자 한 판을 먹을 수 없다. 하지만, 각 친구들은 자신이 먹을 수 있는 피자의 양을 알��

    www.acmicpc.net

    풀이

     

    스스로 풀지 못했고, 질문 게시판의 로직을 참고했다.

    처음에는 왜 예자가 3판인지 문제 이해가 제대로 되지 않았고, 이후에도 1/4과 3/4만 묶는 등 계속해서 문제를 제대로 이해하지 못했다.

    문제의 조건은 1/2, 1/4, 3/4가 한 조각이라는 조건이 있다. 그렇다면 남은 1/2는 1/4 2개로 각각 나눌 수 있다는 것이고, 1/4와 1/2를 합해서 3/4로 줄 수 없다는 말이 된다(양은 맞지만 두조각이기 때문에).

     

    그리고 입력을 받으면서 조건을 처리하는 방식으로 코드를 짰었는데, 이렇게 되면 뒤에 나오는 피자 조각들에 대해 원래는 나눠줄 수 있는데, 새로 한판을 시켜야하는 경우가 생겼다. ~> 최소 피자 판수를 만족하지 못함.

     

    그래서, 모든 입력들에 대해 저장하는 방식으로 코드를 짰다.

    HashMap을 통해, 1/4, 1/2, 3/4가 각각 몇 번 요청이 들어왔는지 횟수를 저장해주었다.

    이후에, 1/4와 3/4이 합쳐질 수 있는 경우를 먼저 세주었다. (3/4은 남은 조각이 1/4밖에 되지 않기때문에, 1/4과 3/4를 우선 검증)

    합친 경우의 수는 한판으로 몇개가 필요한지를 의미하기 때문에, answer에 더해주었다.

    그리고 3/4에 대한 요구가 남아있으면, 해당 숫자 만큼 answer에 더해주었다.(각각 한 판씩 필요하기 때문에)

     

    다음은 남은 1/4 요구와 1/2가 합쳐질 수 있는지 판별해주었다.

    위의 두 경우를 거쳐 최대한 한판으로 만들 수 있는 경우를 만들어 주었고, 남은 1/2, 3/4의 요구가 남아있으면 각각 한판을 만들 수 있는 최소의 경우를 구해 답에 더해주었다.

     

    문제가 생각보다 복잡하다고 여겨져서 코드가 조금 길고 지저분해진 것 같다.

    아무래도 구현 문제다 보니까, 올바른 방향을 찾기가 어려운 것 같다.

     

    구현 문제를 풀다가 막힐 때는, 잠시 쉬었다가 푸는 것도 괜찮은 방법인 것 같다.

     

     

    코드

     

    import java.io.BufferedReader;
    import java.io.IOException;
    import java.io.InputStreamReader;
    import java.util.HashMap;
    
    public class Pizza_3213 {
        final static String[] PIZZAS= {"1/4", "1/2", "3/4"};
        final static int SIZE = 3;
        static int[] PIZZACNT;
    
        public static void main(String[] args) throws IOException {
            System.out.println(solution(new BufferedReader(new InputStreamReader(System.in))));
        }
    
        private static int solution(BufferedReader br) throws IOException{
            int answer =0;
            HashMap<String, Integer> pizzaMap = new HashMap<>();
            PIZZACNT = new int[SIZE];
    
            int friends = Integer.parseInt(br.readLine());
    
            for(int i=0; i<friends; i++) {
                String pizza = br.readLine();
                if(pizzaMap.containsKey(pizza)) {
                    pizzaMap.replace(pizza, pizzaMap.get(pizza)+1);
                } else {
                    pizzaMap.put(pizza,1);
                }
            }
            for(int i=0; i<SIZE; i++) {
                String pizza = PIZZAS[i];
                if(pizzaMap.containsKey(pizza)) {
                    PIZZACNT[i] = pizzaMap.get(pizza);
                }
            }
            answer += canCombine(0,2); // 1/4랑 3/4 같이 묶을 수 있는 경우, 먼저 처리
            answer += PIZZACNT[2];  // 남은 3/4짜리가 있다면, 한판으로 시켜야함
            answer += canCombine(0,1); // 1/4랑 1/2 같이 묶을 수 있는 경우, 처리
            answer += PIZZACNT[1]/2; // 1/2 2개당 한판
            answer += PIZZACNT[1]%2; // 1/2가 홀수면 한판 추가
            answer += PIZZACNT[0]/4; // 1/4 4개당 한판
            answer += PIZZACNT[0]%4; // 4개로 묶었을 때, 남는게 있으면
    
            br.close();
    
            return answer;
        }
    
        private static int canCombine(int idx1, int idx2) {
            int min;
            if(idx2==2) { // 1/4랑 3/4 컴바인
                min = Math.min(PIZZACNT[idx1], PIZZACNT[idx2]);
                PIZZACNT[idx1] -= min;
                PIZZACNT[idx2] -= min;
            } else { // 1/4랑 1/2 컴바인
                min = Math.min(PIZZACNT[idx1]/2, PIZZACNT[idx2]);
                PIZZACNT[idx1] -= min*2;
                PIZZACNT[idx2] -= min;
                if(PIZZACNT[idx1] !=0 && PIZZACNT[idx2] !=0) {    // 남은게 있네? ~> 하나씩 묶어주자
                    PIZZACNT[idx1]--;
                    PIZZACNT[idx2]--;
                    min++;
                }
            }
            return min;
        }
    }
    반응형

    '알고리즘 > 백준' 카테고리의 다른 글

    BOJ) 백조의 호수  (207) 2020.06.12
    BOJ) 연속합  (0) 2020.06.12
    BOJ) 좋은 대회  (0) 2020.06.11
    BOJ) 비트 우정지수  (0) 2020.06.10
    BOJ) 도로와 신호등  (0) 2020.06.10

    댓글

Designed by Tistory.