Softeer 업무처리 (Lv3)

김민주·2023년 2월 15일
0

알고리즘 문제풀이

목록 보기
8/14

문제

https://softeer.ai/practice/info.do?idx=1&eid=1256


코드

package day0215;

import java.io.*;
import java.util.*;

public class Softeer_업무처리 {

	static int H, K, R, ans;
    static Worker[] tree;

    public static void main(String args[]) throws IOException
    {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        StringTokenizer st = new StringTokenizer(br.readLine());

        H = Integer.parseInt(st.nextToken());   // 조직도 높이
        K = Integer.parseInt(st.nextToken());   // 업무 개수
        R = Integer.parseInt(st.nextToken());   // 업무 진행날짜

        tree = new Worker[(int)Math.pow(2, H+1)];
        init(1, 0);     // root의 인덱스 = 1

        // 말단 직원들의 할당 업무 저장
        for(int i=(int)Math.pow(2, H); i<(int)Math.pow(2, H+1); i++) {
            st = new StringTokenizer(br.readLine());
            for(int j=0; j<K; j++) {
                tree[i].job.offer(Integer.parseInt(st.nextToken()));
            }
        }

        for(int i=1; i<=R; i++) {   // top-down 방식 (루트 직원의 일부터 처리)
            workProcess(1, i, 0);
        }

        System.out.println(ans);
    }

    public static void workProcess(int idx, int d, int depth) {
        if(depth > H) return;

        Worker worker = tree[idx];
        if(depth == H && !worker.job.isEmpty()) {
            int curJob = worker.job.poll();
            if(idx%2 == 0) tree[idx/2].leftJob.offer(curJob);   // 짝수 말단직원인 경우 -> 상사의 왼쪽 job에 추가
            else tree[idx/2].rightJob.offer(curJob);            // 홀수 말단직원인 경우 -> 상사의 오른쪽 job에 추가
        } else if(depth < H && d%2 == 0 && !worker.rightJob.isEmpty()) {    // 짝수 날
            int curJob = worker.rightJob.poll();

            if(idx == 1) ans += curJob;    // 루트라면 완료된 job 추가
            else {
                if(idx%2 == 0) tree[idx/2].leftJob.offer(curJob);   
                else tree[idx/2].rightJob.offer(curJob);          
            }
        } else if(depth < H && d%2 == 1 && !worker.leftJob.isEmpty()) {     // 홀수 날
            int curJob = worker.leftJob.poll();

            if(idx == 1) ans += curJob;    // 루트라면 완료된 job 추가
            else {
                if(idx%2 == 0) tree[idx/2].leftJob.offer(curJob);   
                else tree[idx/2].rightJob.offer(curJob);          
            }
        }

        workProcess(idx*2, d, depth+1);     // 왼쪽 자식노드 작업처리
        workProcess(idx*2+1, d, depth+1);   // 오른쪽 자식노드 작업처리
    }

    public static void init(int idx, int depth) {
        if(depth > H) return;

        Worker newWorker = new Worker(depth);
        tree[idx] = newWorker;

        init(idx*2, depth+1);       // 왼쪽 자식
        init(idx*2+1, depth+1);     // 오른쪽 자식
    }

    public static class Worker {
        int depth;
        Queue<Integer> leftJob;
        Queue<Integer> rightJob;
        Queue<Integer> job;

        public Worker(int depth) {
            this.depth = depth;
            initJob();
        }

        public void initJob() {
            if(depth == H) {    // 말단 직원인 경우
                job = new LinkedList<>();
            } else {    // 그 외 직원인 경우
                leftJob = new LinkedList<>();
                rightJob = new LinkedList<>();
            }
        }
    }
}
profile
백엔드 개발자

0개의 댓글