개발자 톡

연습문제 톡 [HSAT 3회 정기 코딩 인증평가 기출] 교차로

java 정답 코드

등록일
2025-01-26 15:22:48
조회수
99
작성자
tjsqls2067
class Car {
    public Car(String loc, int idx){
        this.loc = loc;
        this.idx = idx;
    }


    public String loc;
    public int idx;
}


public class Main {


    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int N = Integer.parseInt(sc.nextLine());


        // ABCD에 대한 각각의 대기큐
        LinkedList<Car> waitQueueA = new LinkedList<>();
        LinkedList<Car> waitQueueB = new LinkedList<>();
        LinkedList<Car> waitQueueC = new LinkedList<>();
        LinkedList<Car> waitQueueD = new LinkedList<>();


        // 차량 통과시간 기록
        long[] carOutTime = new long[N];
        for(int i = 0; i < N; i++) carOutTime[i] = -1;


        // 차량 진입 입력을 "진입시간"을 기준으로 정리
        // "진입시간"을 기준으로 오름차순 정렬
        HashMap<Long, List<Car>> map = new HashMap<>();
        for(int i = 0; i < N; i++){
            String[] input = sc.nextLine().split(" ");
            long time = Long.parseLong(input[0]);
            String loc = input[1];
            int idx = i;
            Car car = new Car(loc,idx);


            if(map.containsKey(time)){
                map.get(time).add(car);
            }else{
                map.put(time,new LinkedList<Car>());
                map.get(time).add(car);
            }
        }


        LinkedList<Map.Entry<Long, List<Car>>> sortedCmdList = map.entrySet().stream()
            .sorted(Map.Entry.comparingByKey())
            .collect(Collectors.toCollection(LinkedList::new));


        
        long curTime = 0L;


        // ABCD에 차량이 대기하고 있거나, 진입 명령(or 차량)이 남아있는 동안 반복문 수행
        while(
            waitQueueA.size() > 0 || waitQueueB.size() > 0 ||
            waitQueueC.size() > 0 || waitQueueD.size() > 0 ||
            sortedCmdList.size() > 0
        ){
            // 진입 명령에 명시된 시간과 현재시간이 일치한다면, 차량 대기큐에 차량 추가
            if(sortedCmdList.size() > 0 && sortedCmdList.get(0).getKey() == curTime){
                List<Car> carList = sortedCmdList.poll().getValue();
                for(Car car : carList){
                    if("A".equals(car.loc)) waitQueueA.add(car);
                    else if ("B".equals(car.loc)) waitQueueB.add(car);
                    else if ("C".equals(car.loc)) waitQueueC.add(car);
                    else if ("D".equals(car.loc)) waitQueueD.add(car);
                }
            }


            // 각 위치의 오른쪽에 차량이 대기중인지 확인
            boolean aRightExist = false;
            boolean bRightExist = false;
            boolean cRightExist = false;
            boolean dRightExist = false;


            if(waitQueueA.size() > 0 && waitQueueD.size() > 0) aRightExist = true;
            if(waitQueueD.size() > 0 && waitQueueC.size() > 0) dRightExist = true;
            if(waitQueueC.size() > 0 && waitQueueB.size() > 0) cRightExist = true;
            if(waitQueueB.size() > 0 && waitQueueA.size() > 0) bRightExist = true;


            // 데드락
            if(aRightExist && bRightExist && cRightExist && dRightExist){
                break;
            }


            // 각 위치에 대해, 차량 통과가 가능하면 통과
            // 통과시간에 대해 기록
            // idx : 입력시 순서번호
            if(!aRightExist && waitQueueA.size() > 0){
                Car car = waitQueueA.poll();
                carOutTime[car.idx] = curTime;
            }
            if(!bRightExist && waitQueueB.size() > 0){
                Car car = waitQueueB.poll();
                carOutTime[car.idx] = curTime;
            }
            if(!cRightExist && waitQueueC.size() > 0){
                Car car = waitQueueC.poll();
                carOutTime[car.idx] = curTime;
            }
            if(!dRightExist && waitQueueD.size() > 0){
                Car car = waitQueueD.poll();
                carOutTime[car.idx] = curTime;
            }


            // curTime++로만 시간을 늘리면, 시간 복잡도에서 실패
            // 따라서, 시간을 점프시킬 수 있다면, 다음 차량 진입 시점으로 이동
            if( waitQueueA.size() == 0 && waitQueueB.size() == 0 &&
                waitQueueC.size() == 0 && waitQueueD.size() == 0 &&
                sortedCmdList.size() > 0){
                curTime = sortedCmdList.get(0).getKey();
            }else{
                curTime++;
            }
        }


        for(int i = 0; i < carOutTime.length; i++){
            System.out.println(carOutTime[i]);
        }
    }
}
#[HSAT_3회_정기_코딩_인증평가_기출]_교차로

이 카테고리의 톡 더보기