https://www.acmicpc.net/problem/21939
Key
1) recommend x
x == 1
이면, 가장 어려운 문제 번호 출력 (다수일 경우, 문제 번호 큰 것 출력)
=> PriorityQueue<Problem>
: 문제 난이도 높은 순 정렬
x == -1
이면, 가장 쉬운 문제 번호 출력 (다수일 경우, 문제 번호 작은 것 출력)
=> PriorityQueue<Problem>
: 문제 난이도 낮은 순 정렬
2) add P L
HashMap
에는 그대로 put
가능PriorityQueue<Problem>
에는 기존에 있던 문제 삭제하고 새로 추가3) solved P
HashMap<Integer, Problem>
: 문제 번호 p 가 Key, 문제가 Value
=> 문제 Problem
: 문제 번호, 문제 난이도
PriorityQueue<Problem>
2개: 문제 난이도 높은 순 / 낮은 순 정렬
=> "recommend 1", "recommend -1" 각각 PriorityQueue<Problem>
사용
1) 초기 입력, 추천 문제 리스트 저장
HashMap
에 저장: O(n)PriorityQueue
2개에 저장: O(2n log_2 n)2) 입력 명령어 수행
HashMap
: O(m)PriorityQueue
: O(n log_2 n)import java.io.*;
import java.util.*;
class Problem {
public int pIdx, level; // 문제 번호, 난이도
public Problem(int pIdx, int level) {
this.pIdx = pIdx;
this.level = level;
}
}
public class Main {
static int n; // 추천 문제 리스트의 문제 개수
static int m; // 명령어 개수
static StringBuilder sb = new StringBuilder();
static Map<Integer, Problem> map = new HashMap<>(); // 문제 추천 리스트 저장
static PriorityQueue<Problem> easyProblems = new PriorityQueue<>(
// 난이도 낮은 순으로 저장 (다수일 경우, 문제 번호 작은 순)
new Comparator<Problem>() {
@Override
public int compare(Problem o1, Problem o2) {
if (o1.level != o2.level)
return o1.level - o2.level;
else
return o1.pIdx - o2.pIdx;
}
}
);
static PriorityQueue<Problem> hardProblems = new PriorityQueue<>(
// 난이도 높은 순으로 저장 (다수일 경우, 문제 번호 큰 순)
new Comparator<Problem>() {
@Override
public int compare(Problem o1, Problem o2) {
if (o2.level != o1.level)
return o2.level - o1.level;
else
return o2.pIdx - o1.pIdx;
}
}
);
static void add(int pIdx, int level) {
Problem newProblem = new Problem(pIdx, level);
// 추천 문제 리스트에 없던 새로운 문제 번호 입력
if (!map.containsKey(pIdx)) {
easyProblems.add(newProblem);
hardProblems.add(newProblem);
}
// 추천 문제 리스트에 있던 문제 번호가 새로운 난이도로 입력
else {
Problem oldProblem = map.get(pIdx); // 2개의 우선순위 큐에서 기존 문제 삭제
easyProblems.remove(oldProblem);
hardProblems.remove(oldProblem);
easyProblems.add(newProblem); // 새로 문제 추가
hardProblems.add(newProblem);
}
map.put(pIdx, newProblem);
}
static void solved(int pIdx) {
Problem removedProblem = map.remove(pIdx);
easyProblems.remove(removedProblem);
hardProblems.remove(removedProblem);
}
static void recommend(int x) {
if (x == 1) {
Problem hardProblem = hardProblems.peek();
sb.append(hardProblem.pIdx).append("\n");
}
else if (x == -1) {
Problem easyProblem = easyProblems.peek();
sb.append(easyProblem.pIdx).append("\n");
}
}
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(
new InputStreamReader(System.in)
);
StringTokenizer st;
// 1) HashMap, 2개 PriorityQueue 에 입력 추천 문제 리스트 저장
n = Integer.parseInt(br.readLine());
for (int i = 0; i < n; i++) {
st = new StringTokenizer(br.readLine());
int pIdx = Integer.parseInt(st.nextToken());
int level = Integer.parseInt(st.nextToken());
Problem problem = new Problem(pIdx, level);
map.put(pIdx, problem);
easyProblems.add(problem);
hardProblems.add(problem);
}
// 2) m개 명령어 수행
m = Integer.parseInt(br.readLine());
for (int i = 0; i < m; i++) {
st = new StringTokenizer(br.readLine());
String command = st.nextToken();
if (command.equals("add")) {
int pIdx = Integer.parseInt(st.nextToken());
int level = Integer.parseInt(st.nextToken());
add(pIdx, level);
}
else if (command.equals("solved")) {
int pIdx = Integer.parseInt(st.nextToken());
solved(pIdx);
}
else if (command.equals("recommend")) {
int x = Integer.parseInt(st.nextToken());
recommend(x);
}
}
System.out.println(sb);
}
}
Key
1) recommend x
x == 1
이면, 가장 어려운 문제 번호 출력 (다수일 경우, 문제 번호 큰 것 출력)x == -1
이면, 가장 쉬운 문제 번호 출력 (다수일 경우, 문제 번호 작은 것 출력)TreeSet<Problem>
: 문제 난이도 낮은 순 정렬하여 first
, last
원소에 접근2) add P L
HashMap
에는 그대로 put
가능TreeSet<Problem>
에는 기존에 있던 문제 삭제하고 새로 추가3) solved P
HashMap<Integer, Problem>
: 문제 번호 p 가 Key, 문제가 Value
=> 문제 Problem
: 문제 번호, 문제 난이도
TreeSet<Problem>
: 문제 난이도 낮은 순 정렬 (다수일 경우, 문제 번호 작은 순 정렬)
=> first
, last
원소에 접근
인터페이스인
Set<>
으로 선언하면first()
,last()
메소드 사용 불가능
- 정렬된 원소들에서 맨 앞 / 맨 뒤 원소에 접근하려면,
TreeSet<>
으로 선언할 것
1) 초기 입력, 추천 문제 리스트 저장
HashMap
에 저장: O(n)TreeSet
에 저장: O(n log_2 n)2) 입력 명령어 수행
HashMap
: O(m)TreeSet
: O(m log_2 n)import java.io.*;
import java.util.*;
class Problem implements Comparable<Problem> {
public int pIdx, level; // 문제 번호, 난이도
public Problem(int pIdx, int level) {
this.pIdx = pIdx;
this.level = level;
}
// 난이도 낮은 순 (다수일 경우, 문제 번호 작은 순)
public int compareTo(Problem o) {
if (this.level != o.level)
return this.level - o.level;
else
return this.pIdx - o.pIdx;
}
}
public class Main2 {
static int n; // 추천 문제 리스트의 문제 개수
static int m; // 명령어 개수
static StringBuilder sb = new StringBuilder();
static Map<Integer, Problem> map = new HashMap<>(); // 문제 추천 리스트 저장
static TreeSet<Problem> treeSet = new TreeSet<>(); // 문제 난이도 낮은 순 (다수일 경우, 문제 번호 낮은 순)
static void add(int pIdx, int level) {
Problem newProblem = new Problem(pIdx, level);
// 추천 문제 리스트에 없던 새로운 문제 번호 입력
if (!map.containsKey(pIdx)) {
treeSet.add(newProblem);
}
// 추천 문제 리스트에 있던 문제 번호가 새로운 난이도로 입력
else {
Problem oldProblem = map.get(pIdx); // 기존 문제 삭제
treeSet.remove(oldProblem);
treeSet.add(newProblem); // 새로 문제 추가
}
map.put(pIdx, newProblem);
}
static void solved(int pIdx) {
Problem removedProblem = map.remove(pIdx);
treeSet.remove(removedProblem);
}
static void recommend(int x) {
if (x == 1) {
Problem hardProblem = treeSet.last();
sb.append(hardProblem.pIdx).append("\n");
}
else if (x == -1) {
Problem easyProblem = treeSet.first();
sb.append(easyProblem.pIdx).append("\n");
}
}
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(
new InputStreamReader(System.in)
);
StringTokenizer st;
// 1) HashMap, TreeSet 에 입력 추천 문제 리스트 저장
n = Integer.parseInt(br.readLine());
for (int i = 0; i < n; i++) {
st = new StringTokenizer(br.readLine());
int pIdx = Integer.parseInt(st.nextToken());
int level = Integer.parseInt(st.nextToken());
Problem problem = new Problem(pIdx, level);
map.put(pIdx, problem);
treeSet.add(problem);
}
// 2) m개 명령어 수행
m = Integer.parseInt(br.readLine());
for (int i = 0; i < m; i++) {
st = new StringTokenizer(br.readLine());
String command = st.nextToken();
if (command.equals("add")) {
int pIdx = Integer.parseInt(st.nextToken());
int level = Integer.parseInt(st.nextToken());
add(pIdx, level);
}
else if (command.equals("solved")) {
int pIdx = Integer.parseInt(st.nextToken());
solved(pIdx);
}
else if (command.equals("recommend")) {
int x = Integer.parseInt(st.nextToken());
recommend(x);
}
}
System.out.println(sb);
}
}