1
+ import java .io .*;
2
+ import java .util .*;
3
+
4
+ /*
5
+ * 초밥 회전 시스템을 구현을 통해 관리하면 매우 복잡해짐
6
+ *
7
+ * 주방장이 만든 초밥이 손님에게 도달하는 시간을 계산한 뒤, 사라지는 시간
8
+ * 손님들이 초밥을 다 먹고 떠나는 시간을 계산하여 쿼리에 추가
9
+ *
10
+ * 초밥과 손님의 입장과 퇴장을 쿼리로 표현하여 시간 순으로 처리...
11
+ * 모든 행동들이 시간 순으로 일어나기 때문에, 이렇게 구현하면 된다고 한다..!
12
+ */
13
+
14
+ public class DH_코드트리_오마카세 {
15
+ static class Query implements Comparable <Query > {
16
+ int cmd , t , x , n ;
17
+ String name ;
18
+
19
+ public Query (int cmd , int t , int x , int n , String name ) {
20
+ this .cmd = cmd ;
21
+ this .t = t ;
22
+ this .x = x ;
23
+ this .n = n ;
24
+ this .name = name ;
25
+ }
26
+
27
+ @ Override
28
+ public int compareTo (Query o ) {
29
+ if (this .t != o .t ) return Integer .compare (this .t , o .t ); // 시간 순
30
+ return Integer .compare (this .cmd , o .cmd ); // 명령순
31
+ }
32
+ }
33
+ static class Time {
34
+ int in , out ;
35
+
36
+ public Time (int in ) {
37
+ this .in = in ;
38
+ }
39
+
40
+ public void setOutTime (int time ) {
41
+ this .out = Math .max (time , this .out );
42
+ }
43
+
44
+ }
45
+ static int L , Q ;
46
+
47
+ // 쿼리가 시간 순으로 입력될 수 있도록 함
48
+ static ArrayList <Query > query = new ArrayList <>();
49
+ static HashSet <String > people = new HashSet <String >(); // 등장한 사람 목록 관리
50
+ static HashMap <String , PriorityQueue <Query >> pQuery = new HashMap <>(); // 사람들마다 쿼리를 관리함
51
+ static HashMap <String , Integer > pos = new HashMap <>(); // 사람들마다 위치 관리
52
+ static HashMap <String , Time > time = new HashMap <>(); // 사람들의 출입 시간 관리
53
+ static StringBuilder sb = new StringBuilder ();
54
+
55
+ public static void main (String [] args ) throws Exception {
56
+ System .setIn (new FileInputStream ("./input/코드트리오마카세.txt" ));
57
+
58
+ BufferedReader br = new BufferedReader (new InputStreamReader (System .in ));
59
+ StringTokenizer st = new StringTokenizer (br .readLine ());
60
+
61
+ L = Integer .parseInt (st .nextToken ());
62
+ Q = Integer .parseInt (st .nextToken ());
63
+
64
+ for (int q = 0 ; q < Q ; q ++) {
65
+
66
+ st = new StringTokenizer (br .readLine ());
67
+
68
+ int cmd = Integer .parseInt (st .nextToken ());
69
+ int t = 0 , x = 0 , n = 0 ;
70
+ String name = null ;
71
+
72
+ if (cmd == 100 ) {
73
+ t = Integer .parseInt (st .nextToken ());
74
+ x = Integer .parseInt (st .nextToken ());
75
+ name = st .nextToken ();
76
+
77
+ if (pQuery .get (name ) == null ) pQuery .put (name , new PriorityQueue <>());
78
+ pQuery .get (name ).add (new Query (cmd , t , x , n , name ));
79
+ }
80
+
81
+ if (cmd == 200 ) {
82
+ t = Integer .parseInt (st .nextToken ());
83
+ x = Integer .parseInt (st .nextToken ());
84
+ name = st .nextToken ();
85
+ n = Integer .parseInt (st .nextToken ());
86
+
87
+ people .add (name );
88
+
89
+ time .put (name , new Time (t ));
90
+ pos .put (name , x );
91
+ }
92
+
93
+ if (cmd == 300 ) {
94
+ t = Integer .parseInt (st .nextToken ());
95
+ }
96
+
97
+ query .add (new Query (cmd , t , x , n , name ));
98
+ }
99
+
100
+ // 각 사람마다 자신의 이름이 적힌 초밥을 언제 먹게 되는지 계산하고, 기존 쿼리에 추가
101
+ for (String p : people ) {
102
+
103
+ // 마지막으로 먹는 초밥 중 가장 늦은 시간이 됨!
104
+ while (!pQuery .get (p ).isEmpty ()) {
105
+ Query current = pQuery .get (p ).poll ();
106
+
107
+ int removeTime = 0 ; // 사람이 나가게 되는 시간
108
+
109
+ // 초밥 - 사람
110
+ // 초밥이 사람이 등장하기 전에 미리 주어진 상황
111
+ if (current .t < time .get (p ).in ) {
112
+
113
+ // 사람이 들어왔을 때, 초밥의 위치
114
+ int sushiPos = (current .x + (time .get (p ).in - current .t )) % L ;
115
+ int addTime = (pos .get (p ) - sushiPos + L ) % L ;
116
+
117
+ removeTime = time .get (p ).in + addTime ;
118
+ }
119
+
120
+ // 사람 - 초밥
121
+ else {
122
+ int addTime = (pos .get (p ) - current .x + L ) % L ;
123
+ removeTime = current .t + addTime ;
124
+ }
125
+
126
+ time .get (p ).setOutTime (removeTime ); // 나가는 시간을 제일 마지막 초밥을 먹는 시간으로 설정해야 됨
127
+
128
+ // 초밥이 사라지는 쿼리 추가
129
+ query .add (new Query (111 , removeTime , 0 , 0 , p ));
130
+ }
131
+ }
132
+
133
+ // 사람들이 나가는 쿼리 추가
134
+ for (String p : people ) query .add (new Query (222 , time .get (p ).out , 0 , 0 , p ));
135
+
136
+ Collections .sort (query );
137
+
138
+ int sushiCnt = 0 , peopleCnt = 0 ;
139
+
140
+ for (Query current : query ) {
141
+
142
+ if (current .cmd == 100 ) sushiCnt ++; // 초밥이 생겼다가
143
+ else if (current .cmd == 111 ) sushiCnt --; // 초밥을 먹었다가
144
+ else if (current .cmd == 200 ) peopleCnt ++; // 사람이 들어왔다가
145
+ else if (current .cmd == 222 ) peopleCnt --; // 사람이 나갔다가
146
+ else sb .append (peopleCnt ).append (" " ).append (sushiCnt ).append ("\n " );
147
+ }
148
+
149
+ System .out .println (sb );
150
+ }
151
+
152
+ }
0 commit comments