알고리즘 풀이/Java

[알고리즘] 코드트리 오카마세

Dong's Universe 2024. 3. 25. 15:18

https://www.codetree.ai/training-field/frequent-problems/problems/codetree-omakase/description?page=1&pageSize=20

 

코드트리 | 코딩테스트 준비를 위한 알고리즘 정석

국가대표가 만든 코딩 공부의 가이드북 코딩 왕초보부터 꿈의 직장 코테 합격까지, 국가대표가 엄선한 커리큘럼으로 준비해보세요.

www.codetree.ai

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.PriorityQueue;
import java.util.StringTokenizer;

public class Main {
	
	static class Wait {
		int time;
		String name;
		public Wait(int time, String name) {
			super();
			this.time = time;
			this.name = name;
		}
	}
	
	static class Sushi {
		int t;
		int x;
		String name;
		public Sushi(int t, int x, String name) {
			super();
			this.t = t;
			this.x = x;
			this.name = name;
		}
	}
	
	static class Guest {
		int t;
		int x;
		String name;
		int n;
		public Guest(int t, int x, String name, int n) {
			super();
			this.t = t;
			this.x = x;
			this.name = name;
			this.n = n;
		}
		
	}
	static StringTokenizer st;
	static int L;
	static int Q;
	static PriorityQueue<Wait> pq;
	static HashMap<String, List<Sushi>> junk;
	static int junkSize = 0;
	static HashMap<String, Guest> guests;
	
	static StringBuilder sb = new StringBuilder();
	public static void main(String[] args) throws Exception {
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		st = new StringTokenizer(br.readLine());
		L = Integer.parseInt(st.nextToken());
		Q = Integer.parseInt(st.nextToken());
		
		pq = new PriorityQueue<>(new Comparator<Wait>() {

			@Override
			public int compare(Wait o1, Wait o2) {
				return o1.time - o2.time;
			}
		});

		junk = new HashMap<>();
		guests = new HashMap<>();
		for (int i = 0; i < Q; i++) {
			st = new StringTokenizer(br.readLine());
			int cmd = Integer.parseInt(st.nextToken());
			switch (cmd) {
				case 100:
					makeSushi();
					break;
	
				case 200:
					guestIn();
					break;
				
				case 300:
					photo();
					break;
			}
		}
		System.out.println(sb);
	}
		
	private static void photo() {
		int t = Integer.parseInt(st.nextToken());
		while (true) {
			Wait peek = pq.peek();
			if (pq.isEmpty()) {
				break;
			}
			if (t >= peek.time) {
				pq.poll();
				if (!guests.containsKey(peek.name)) {
					continue;
				}
				Guest guest = guests.get(peek.name);
				guest.n--;
				if (guest.n == 0) {
					guests.remove(peek.name);
				}
			} else {
				break;
			}
		}
		
		int person = guests.size();
		
		int sushi = junkSize + pq.size();
		sb.append(person).append(" ").append(sushi).append("\n");
	}
	private static void guestIn() {
		int t = Integer.parseInt(st.nextToken());
		int x = Integer.parseInt(st.nextToken());
		String name = st.nextToken();
		int n = Integer.parseInt(st.nextToken());
		
		Guest guest = new Guest(t, x, name, n);

		guests.put(name, guest);
		List<Sushi> junkSushi = junk.get(name);
		//예외처리 해주어야함
		if (junkSushi == null) {
			return;
		}
		for (Sushi sushi : junkSushi) {
			pq.add(new Wait(findEatTime(sushi.t, sushi.x, guest), name));
			junkSize--;
		}
	}
	private static void makeSushi() {
		int t = Integer.parseInt(st.nextToken());
		int x = Integer.parseInt(st.nextToken());
		String name = st.nextToken();
		
		if (!guests.containsKey(name)) {
			if (!junk.containsKey(name)) {
				junk.put(name, new ArrayList<>());
			}
			junk.get(name).add(new Sushi(t, x, name));
			junkSize++;
			return;
		}
		
		Guest guest = guests.get(name);
		pq.add(new Wait(findEatTime(t, x, guest), name));		
	}
	private static int findEatTime(int t, int x, Guest guest) {
		int time = findTime(guest, t, x);
		while (time < guest.t) {
			time += L;
		}
		return time;
	}
	private static int findTime(Guest guest, int t, int x) {
		int time;
		if (guest.x - x < 0) {
			time = guest.x - x + L + t;
		} else {
			time = guest.x - x + t;
		}
		return time;
	}
}

나의 풀이

- 병관이 풀이 참고

- 게스트가 들어올때 정크가 없는 경우를 고려해주지 않아 틀림

- 느끼는 건 어떤 문제든 창의적으로 풀어야 하는 요소가 존재한다는 것이다!!!