728x90
문제
tony9402는 최근 깃헙에 코딩테스트 대비 문제를 직접 뽑아서 "문제 번호, 난이도"로 정리해놨다.
깃헙을 이용하여 공부하시는 분들을 위해 새로운 기능을 추가해보려고 한다.
만들려고 하는 명령어는 총 3가지가 있다. 아래 표는 각 명령어에 대한 설명이다.
recommend 𝑥 | 𝑥가 1인 경우 추천 문제 리스트에서 가장 어려운 문제의 번호를 출력한다. 만약 가장 어려운 문제가 여러 개라면 문제 번호가 큰 것으로 출력한다. 𝑥가 -1인 경우 추천 문제 리스트에서 가장 쉬운 문제의 번호를 출력한다. 만약 가장 쉬운 문제가 여러 개라면 문제 번호가 작은 것으로 출력한다. |
add 𝑃 𝐿 | 추천 문제 리스트에 난이도가 𝐿인 문제 번호 𝑃를 추가한다. (추천 문제 리스트에 없는 문제 번호 𝑃만 입력으로 주어진다. 이전에 추천 문제 리스트에 있던 문제 번호가 다른 난이도로 다시 들어 올 수 있다.) |
solved 𝑃 | 추천 문제 리스트에서 문제 번호 𝑃를 제거한다. (추천 문제 리스트에 있는 문제 번호 𝑃만 입력으로 주어진다.) |
명령어 recommend는 추천 문제 리스트에 문제가 하나 이상 있을 때만 주어진다.
명령어 solved는 추천 문제 리스트에 문제 번호가 하나 이상 있을 때만 주어진다.
위 명령어들을 수행하는 추천 시스템을 만들어보자.
입력
첫 번째 줄에 추천 문제 리스트에 있는 문제의 개수 𝑁 가 주어진다.
두 번째 줄부터 𝑁+1줄까지 문제 번호 𝑃 와 난이도 𝐿가 공백으로 구분되어 주어진다.
𝑁+2줄은 입력될 명령문의 개수 𝑀이 주어진다.
그 다음줄부터 𝑀개의 위에서 설명한 명령문이 입력된다.
출력
recommend 명령이 주어질 때마다 문제 번호를 한 줄씩 출력한다. 최소 한번의 recommend 명령어가 들어온다.
해결 코드
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.*;
public class Main {
public static void main(String[] args) throws Exception{
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
int N = Integer.parseInt(br.readLine());
//가장 어려운 문제 순으로 정렬
PriorityQueue<Problem> largestPQ = new PriorityQueue<>(Collections.reverseOrder());
//가장 쉬운 문제 순으로 정렬
PriorityQueue<Problem> smallestPQ = new PriorityQueue<>();
//문제 번호당 난이도를 저장한 배열(최대 문제 번호 값 100,000)
int[] levels = new int[100_001];
//기본 추천 문제 리스트 초기화
for(int i=0;i<N;i++){
StringTokenizer st = new StringTokenizer(br.readLine());
int num = Integer.parseInt(st.nextToken());
int level = Integer.parseInt(st.nextToken());
levels[num] = level;
Problem problem = new Problem(num,level);
largestPQ.add(problem);
smallestPQ.add(problem);
}
Set<String> solveSet = new HashSet<>();
int M = Integer.parseInt(br.readLine());
//추가 문제 더함
for(int i=0;i<M;i++){
StringTokenizer st = new StringTokenizer(br.readLine());
String command = st.nextToken();
//문제를 추가하는 경우 해당 번호의 난이도를 갱신하고 각 최대/최소 문제 큐에 문제 추가
if(command.equals("add")){
int num = Integer.parseInt(st.nextToken());
int level = Integer.parseInt(st.nextToken());
levels[num] = level;
Problem problem = new Problem(num,level);
largestPQ.add(problem);
smallestPQ.add(problem);
}
//문제를 추천하는 경우 번호-난이도의 키를 이용해 이미 풀어낸 문제를 제거
else if(command.equals("recommend")){
int val = Integer.parseInt(st.nextToken());
if(val == 1){
//번호-난이도로 키 생성
String key = largestPQ.peek().num +"-"+largestPQ.peek().level;
//이미 푼 문제를 제거
while(solveSet.contains(key)){
largestPQ.poll();
key = largestPQ.peek().num +"-"+largestPQ.peek().level;
}
System.out.println(largestPQ.peek().num);
}else{
//번호-난이도로 키 생성
String key = smallestPQ.peek().num +"-"+smallestPQ.peek().level;
//이미 푼 문제를 제거
while(solveSet.contains(key)){
smallestPQ.poll();
key = smallestPQ.peek().num +"-"+smallestPQ.peek().level;
}
System.out.println(smallestPQ.peek().num);
}
}else{
int num = Integer.parseInt(st.nextToken());
//문제-난이도 키를 등록
solveSet.add(num+"-"+levels[num]);
}
}
}
}
class Problem implements Comparable<Problem>{
int num;
int level;
public Problem(int num, int level){
this.num = num;
this.level = level;
}
@Override
public int compareTo(Problem o) {
if(this.level == o.level){
return this.num - o.num;
}
return this.level - o.level;
}
}
실행 결과
팁
- 방문배열이 너무 커지면 set을 이용해 생성하자
- 데이터의 고유키가 무엇인지 확인해보자. 복합키의 경우의 수도 있다.
'알고리즘 문제 풀이 > 해결코드' 카테고리의 다른 글
[백준 - 1351][GOLD 5][해설 X] - 무한 수열 (JAVA) (0) | 2024.07.18 |
---|---|
[백준 - 5966][GOLD 5][해설 X] - Heat Wave (JAVA) (0) | 2024.07.10 |
[백준 - 17203][SILVER 4][해설 X] - ∑|ΔEasyMAX| (JAVA) (0) | 2024.07.07 |
[백준 - 17014][SILVER 1][해설 X] - Pretty Average Primes (JAVA) (0) | 2024.07.06 |
[백준 - 14715][GOLD 5][해설 X] - 전생했더니 슬라임 연구자였던 건에 대하여 (Easy) (JAVA) (0) | 2024.07.05 |