코딩테스트/SWEA_Java

Q. 1860. 진기의 최고급 붕어빵(D3)

Ski_ 2023. 5. 10. 23:01

Q. 1860. 진기의 최고급 붕어빵(D3)

 

0. 문제

 

D3 난이도의 문제이고, 구현 문제라고 생각된다.

N, M, K가 주어진다.

N은 붕어빵을 먹으려는 사람의 수 이고, M초에 K개의 붕어빵을 만들 수 있다.

한 손님은 한 개의 붕어빵을 가져 간다고 하면,

모든 손님들에게 기다리는 시간없이 붕어빵을 제공할 수 있는지 판별하는 프로그램을 작성하라.


1. 풀이

 

1) 손님들이 오는 순서가 차례대로 주어지지 않으므로 먼저 입력을 받은 뒤 정렬을 한다.

2) 그리고 손님들을 받으면서, 만약 현재 붕어빵이 없을 경우

손님의 시간 이하인 K 배수만큼 시간을 더하고, 붕어빵을 만들어서 손님에게 줄 수 있는지 판별한다.

3) 손님에게 줄 수 없을경우 즉시 루프를 종료한다.

시간을 줄이기 위해 손님이 온 시간에 만약 붕어빵이 있을 경우 2)번 동작을 하지 않고 바로 다음 손님을 받았다.

import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Arrays;
import java.util.StringTokenizer;
 
public class Solution {
 
    static BufferedReader br;
    static StringTokenizer st;
    static StringBuilder sb = new StringBuilder();
    static int[] BreadArr;
    static int N, M, K;
     
    public static void input() throws IOException {
         
        st = new StringTokenizer(br.readLine());
        N = Integer.parseInt(st.nextToken());
        M = Integer.parseInt(st.nextToken());
        K = Integer.parseInt(st.nextToken());
         
        st = new StringTokenizer(br.readLine());
        BreadArr = new int[N];
        for (int i = 0; i < N; i++) {
            BreadArr[i] = Integer.parseInt(st.nextToken());
        }
    }
     
    public static void pro(int tc) {
         
        boolean res = true;
         
        Arrays.sort(BreadArr);
        int curTime = 0;
        int curBreadCnt = 0;
         
        for (int i = 0; i < N; i++) {
             
            if (curBreadCnt > 0) {
                curBreadCnt--;
                continue;
            }
             
            if (curTime < BreadArr[i]) {
                int time = (BreadArr[i] - curTime) / M;
                curTime += time * M;
                curBreadCnt += time * K;
            }
             
            if (curBreadCnt > 0) {
                curBreadCnt--;
            } else {
                res = false;
                break;
            }
        }
         
        sb.append(String.format("#%d ", tc));
        if (res) sb.append("Possible");
        else sb.append("Impossible");
        sb.append('\n');
    }
     
     
     
     
    public static void main(String[] args) throws Exception {
         
        //br = new BufferedReader(new InputStreamReader(new FileInputStream("res/input.txt")));
        br = new BufferedReader(new InputStreamReader(System.in));
        int T = Integer.parseInt(br.readLine());
         
        for (int tc = 1; tc <= T; tc++) {
            input();
            pro(tc);
        }
        System.out.println(sb);
    }
 
}

2. 시간복잡도 계산

 

0) 1 ≤ N, M, K ≤ 100 , 0 <= 손님의 도착 시간(A) <= 11111

1) 손님의 도착 시간 저장 - O(N)

2) 손님 배열 정렬 - O(NlogN)

3) 풀이 1번 - O(N)

위 세 연산은 연관성이 없으므로 덧셈으로 시간복잡도를 계산하게 된다.

따라서 시간복잡도는 O(N log N)이고, 시간제한은 2초이므로

1초에 약 1억번 연산을 한다고 가정하면, 1초 이내에 풀 수 있다.


3. 성능 개선 방안

 

1) 손님을 정렬해두고 만약 모든 시간 마다 붕어빵의 수를 미리 계산해두고, 손님을 받았다면 O(N^2)이 걸렸을 것 이다.

하지만 손님이 도착했을 때 붕어빵이 만약 없다면, 손님이 도착하는 시간 전 까지 붕어빵을 만드는 식으로 해서 손님이 O(N)으로 좀 더 빠르게 동작하도록 변경했다.

2) 손님의 수가 최대 100이고, 만약 손님이 왔을 때 조건을 충족하지 않았을 경우 즉시 루프를 종료하게 구현했으므로 조금 더 빠르게 계산할 수 있게 코드를 작성했다.

 

현재 내가 푼 코드는 위 내용을 고려한 코드라, 지금은 더 개선할 방법이 떠오르지 않지만,나중에 생각나면 더 추가해야겠다.


반응형