문제 : boj17162
mod가 최대 10^2라서 뭐 복잡한 알고리즘 필요없이 풀 수 있다. 결국 나누었을 때 0, ..., mod-1인 수가 어느 idx 위치에 있냐가 중요하다. 이걸 빨리 알 수 있으면 되는건데, mod가 10^2이니깐 대충 O(Q * mod) 정도의 시간복잡도만 가져도 풀 수 있다. 그럼 해볼만한게 많이 있다.
내 경우엔 어차피 맨 뒤에서만 수가 추가되고 빠지니 스택을 사용했다. 그리고 mod개 만큼의 스택을 마련했다. 스택배열을 arr이라고 하고, 현재 넣을 위치를 idx라고 하겠다. 그럼 각 쿼리에 대해 다음과 같이 대응할 수 있다.
---
[ 쿼리 : 1 num ]
arr[num % mod]에 num을 추가하고 idx++ -> O(1)
[ 쿼리 : 2 ]
최대 10^2개인 arr을 전부 peek 해보면서 idx-1 값을 가진 스택을 pop한다. 그리고 idx-- -> O(mod)
이건 메모리를 좀 더 써서 HashMap같은걸로 (key, value) = (num, num%mod)를 유지한다면 더 빠르게 구할 수 있다. 하지만 내 경우엔 어차피 쿼리 '3'을 처리하는게 O(mod)만큼 필요하므로, 굳이 메모리 복잡도를 올리지 않기 위해 제외했다.
[ 쿼리 : 3 ]
arr[0]부터 arr[mod-1] 까지 확인하면서 이 중 빈 스택이 있다면 -1이다. 그렇지 않다면 peek을 해봐서 넣었던 idx 중 최소인 값을 찾는다. 최종적으로 '현재 idx - 찾은 최소 idx'가 답이다. -> O(mod)
---
그리고 저런 쿼리가 총 Q개 있으므로 총 O(Q*mod)의 시간복잡도를 가지게 된다.
예시로 다음의 테스트케이스를 한번 그림으로 그려봤다.
8 4
1 2
1 3
1 4
3
2
1 16
1 1
3
코드 : github
import java.io.DataInputStream;
import java.io.IOException;
import java.util.Stack;
public class Main extends FastInput {
private void solution() throws Exception {
int q = nextInt();
int mod = nextInt();
Stack<Integer>[] arr = new Stack[mod];
for (int i = 0; i < mod; i++) arr[i] = new Stack<>();
StringBuilder sb = new StringBuilder();
int idx = 0;
while (q-->0) {
switch (nextInt()) {
case 1 :
int num = nextInt();
arr[num%mod].push(idx++);
break;
case 2 :
for (int i = 0; i < mod; i++) {
if (!arr[i].isEmpty() && arr[i].peek() == idx-1) {
arr[i].pop();
idx--;
break;
}
}
break;
case 3 :
int min = Integer.MAX_VALUE;
for (int i = 0; i < mod; i++) {
if (arr[i].isEmpty()) {
min = -1;
break;
}
if (arr[i].peek() < min) {
min = arr[i].peek();
}
}
sb.append(min==-1?min:idx-min).append('\n');
break;
}
}
System.out.print(sb);
}
public static void main(String[] args) throws Exception {
initFI();
new Main().solution();
}
}
class FastInput {
private static final int DEFAULT_BUFFER_SIZE = 1 << 10;
private static DataInputStream inputStream;
private static byte[] buffer;
private static int curIdx, maxIdx;
protected static void initFI() {
inputStream = new DataInputStream(System.in);
buffer = new byte[DEFAULT_BUFFER_SIZE];
curIdx = maxIdx = 0;
}
protected static int nextInt() throws IOException {
int ret = 0;
byte c = read();
while (c <= ' ') c = read();
do {
ret = ret * 10 + c - '0';
} while ((c = read()) >= '0' && c <= '9');
return ret;
}
private static byte read() throws IOException {
if (curIdx == maxIdx) {
maxIdx = inputStream.read(buffer, curIdx = 0, DEFAULT_BUFFER_SIZE);
if (maxIdx == -1) buffer[0] = -1;
}
return buffer[curIdx++];
}
}
'PS > BOJ' 카테고리의 다른 글
백준 9997 자바 - 폰트 (BOJ 9997 JAVA) (0) | 2022.03.20 |
---|---|
백준 3164 자바 - 패턴 (BOJ 3164 JAVA) (0) | 2022.03.19 |
백준 2602 자바 - 돌다리 건너기 (BOJ 2602 JAVA) (0) | 2022.03.18 |
백준 11637 자바 - 인기 투표 (BOJ 11637 JAVA) (0) | 2022.03.17 |
백준 5568 자바 - 카드 놓기 (BOJ 5568 JAVA) (0) | 2022.03.16 |
댓글