개발자 톡
연습문제 톡
[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회_정기_코딩_인증평가_기출]_교차로