백준_문제 추천 시스템 Version 1

LeeYulhee·2023년 9월 1일
0

💻 문제 출처 : 백준_문제 추천 시스템 Version 1

👉 내가 작성한 답


import java.util.*;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

public class Main {
    public static void main(String[] args) throws IOException {

        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        
        int questionCount = Integer.parseInt(br.readLine());

        TreeSet<Integer> questionLevel = new TreeSet<>();
        Map<Integer, TreeSet<Integer>> questions = new HashMap<>();

        for(int i = 0; i < questionCount; i++) {
            String[] strArray = br.readLine().split(" ");

            int questionNum = Integer.parseInt(strArray[0]);
            int level = Integer.parseInt(strArray[1]);

            questionLevel.add(level);
            questions.computeIfAbsent(level, k -> new TreeSet<>()).add(questionNum);
        }

        int commandCount = Integer.parseInt(br.readLine());

        for(int i = 0; i < commandCount; i++) {
            String[] strArray = br.readLine().split(" ");

            String command = strArray[0];

            switch(command) {
                case "add": int level = Integer.parseInt(strArray[2]);
                            int questionNum = Integer.parseInt(strArray[1]);
                            questionLevel.add(level);
                            questions.computeIfAbsent(level, k -> new TreeSet<>()).add(questionNum);
                            break;
                case "recommend": if(Integer.parseInt(strArray[1]) == 1) {
                                    int questionRecommend = questionLevel.last();
                                    System.out.println(questions.get(questionRecommend).last());
                                  } else {
                                    int questionRecommend = questionLevel.first();
                                    System.out.println(questions.get(questionRecommend).first());
                                  }
                                  break;
                case "solved": int solvedNum = 0;
                               int solvedQuestionNum = Integer.parseInt(strArray[1]);
                               for(Map.Entry<Integer, TreeSet<Integer>> entry : questions.entrySet()) {
                                   if(entry.getValue().floor(solvedQuestionNum) == null) {
                                       continue;
                                   }

                                   int closeQuestionNum = entry.getValue().floor(solvedQuestionNum);
                                   if(closeQuestionNum == solvedQuestionNum) {
                                       solvedNum = entry.getKey();
                                       break;
                                   }
                               } 
                               
                               questions.get(solvedNum).remove(solvedQuestionNum);
                               if(questions.get(solvedNum).isEmpty()) questionLevel.remove(solvedNum);
                               break;
            }
        }

    }
}

📌 문제 풀이 설명

  • BufferedReader 생성
  • int 변수 questionCount에 첫 번째 입력 값을 int로 변환해 대입
  • Integer를 값으로 사용하는 TreeSet questionLevel을 생성
  • Integer를 Key로, TreeSet를 Value 로 사용하는 Map questions를 생성
  • for문으로 0부터 questionCount 미만까지 1씩 증가하며 순회
    • 입력된 값을 “ “로 나눠서 String 배열 strArray에 저장
    • int 변수 questionNum에 strArray[0]을 int로 변환한 값을 대입
    • int 변수 level에 strArray[1]을 int로 변환한 값을 대입
    • questionLevel에 level을 추가
    • questions에 level Key가 있다면 해당하는 TreeSet을 가져와서 questionNum을 추가하고, 없다면 새로 TreeSet을 생성해서 questionNum 추가
  • int 변수 commandCount에 입력된 값을 int로 변환해서 대입
  • for문으로 0부터 commandCount 미만까지 1씩 증가하며 순회
    • 입력되는 값을 “ “로 나눠서 String 배열 strArray에 저장
    • String 변수 command에 strArray[0] 대입
    • switch-case문으로 command의 값에 따라 나눔
      • command가 add인 경우
        • int 변수 level에 strArray[2]를 int로 변환해 대입
        • int 변수 questionNum에 strArray[1]을 int로 변환해 대입
        • questionLevel(TreeSet)에 level 추가
        • questions에 level Key가 있다면 해당하는 TreeSet을 가져와서 questionNum을 추가하고, 없다면 새로 TreeSet을 생성해서 questionNum 추가
      • command가 recommend인 경우
        • 만약 strArray[1]이 1과 같다면
          • int 변수 questionRecommend에 questionLevel의 마지막 값을 대입
            • 가장 어려운 문제
          • questions에서 questionRecommend에 해당하는 TreeSet의 마지막 값을 출력
            • 같은 레벨일 경우 문제 번호가 가장 큰 것
        • 그게 아니라면
          • int 변수 questionRecommend에 questionLevel의 첫 번째 값을 대입
            • 가장 쉬운 문제
          • questions에서 questionRecommend에 해당하는 TreeSet의 첫 번째 값을 출력
            • 같은 레벨일 경우 문제 번호가 가장 작은 것
      • command가 solved인 경우
        - int 변수 solvedNum을 선언하고 0으로 초기화
        - int 변수 solvedQuestionNum을 선언하고 strArray[1]을 int로 변환한 값으로 초기화
        - 향상된 for문으로 questions를 entrySet으로 변환해 순회(문제 번호로 레벨 탐색)
        - 만약 entry의 value인 TreeSet에 solvedQuestionNum과 같거나 더 큰 숫자가 없는 경우 for문으로 돌아가 다음 차례 순회 진행
        - int closeQuestionNum에 entry의 value인 TressSet에 solvedQuestionNum과 같거나 더 큰 숫자(근접한)를 대입
        - 만약 closeQuestionNum이 solvedQuestionNum과 같다면
        - solvedNum에 해당 값의 Key를 대입하고 for문 종료
        - questions에서 solvedNum에 해당하는 TreeSet을 가져와 solvedQuestionNum을 제거
        - 만약 questions에서 solvedNum에 해당하는 TreeSet이 비었다면 questionLevel에서 solvedNum을 제거



👉 다른 사람이 작성한 답


import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.StringTokenizer;
import java.util.TreeSet;

public class Main {
	public static void main(String[] args) throws IOException {
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		
		int N = Integer.parseInt(br.readLine());
		
		StringBuffer sb = new StringBuffer();
		
		int[] difficulty = new int[100001];
		
		TreeSet<Integer> ts = new TreeSet<>((o1, o2) ->  {
			if (difficulty[o2] == difficulty[o1]) return o2-o1;
			else return difficulty[o2] - difficulty[o1];
		});
		
		for (int i = 0; i<N; i++) {
			StringTokenizer st = new StringTokenizer(br.readLine()," ");
			int P = Integer.parseInt(st.nextToken());
			int L = Integer.parseInt(st.nextToken());
			difficulty[P] = L;
			ts.add(P);
		}
		
		int M = Integer.parseInt(br.readLine());
		
		for (int i = 0; i<M; i++) {
			StringTokenizer st = new StringTokenizer(br.readLine()," ");
			switch(st.nextToken()) {
				case("add") :
					int P = Integer.parseInt(st.nextToken());
					int L = Integer.parseInt(st.nextToken());
					difficulty[P] = L;
					ts.add(P);
					break;
				case ("solved") :
					ts.remove(Integer.parseInt(st.nextToken()));
					break;
				case ("recommend") :
					int x = Integer.parseInt(st.nextToken());
					if (x == 1) {
						sb.append(ts.first()).append("\n");
					}
					else {
						sb.append(ts.last()).append("\n");
					}
					break;
			}
		}
		System.out.println(sb);
	}
}

📌 문제 풀이 설명

  • BufferedReader 생성
  • int 변수 N에 입력된 값을 int로 변환해 대입
  • StringBuffer 생성
  • int 배열 difficulty를 100,001의 크기로 생성
    • 문제 번호를 인덱스로 사용해 그 문제의 난이도를 저장하기 위한 용도
  • TreeSet를 생성해서 문제 번호를 저장하되 람다식으로 Comparator를 이용해 정렬 방식 지정
    • difficulty[o2]와 difficulty[o1]을 비교하고, 두 문제의 난이도가 같다면 큰 문제 번호가 먼저 오게 함
    • 두 문제의 난이도가 다르다면 난이도가 높은 문제가 먼저 오도록 정렬
    • ⇒ 난이도가 높은 문제가 먼저 오고, 난이도가 같으면 문제 번호가 큰 것이 오도록 정렬 방식 설정
  • for문으로 0부터 N 미만까지 1씩 증가하며 순회
    • StringTokenizer에 입력된 값을 “ “로 나눠 저장
    • StringTokenizer의 첫 번째 값을 int로 변환해 int 변수 P에 대입
    • StringTokenizer의 다음 값을 int로 변환해 int 변수 L에 대입
    • difficulty[P]에 L을 저장 ⇒ 문제 번호의 인덱스에 문제 난이도를 저장
    • TreeSet에 P를 저장 ⇒ 문제 번호를 TreeSet에 추가
  • int 변수 M에 입력된 값을 int로 변환해 대입
  • for문으로 0부터 M 미만까지 1씩 증가하며 순회
    • StringTokenizer에 입력된 값을 “ “로 나눠 저장
    • switch-case문으로 StringTokenizer의 첫 번째 토큰에 따라 나눔
      • 첫 번째 토큰이 add인 경우
        • StringTokenizer의 다음 값을 int로 변환해 int 변수 P에 대입
        • StringTokenizer의 다음 값을 int로 변환해 int 변수 L에 대입
        • difficulty[P]에 L을 저장 ⇒ 문제 번호의 인덱스에 문제 난이도를 저장
        • TreeSet에 P를 저장 ⇒ 문제 번호를 TreeSet에 추가
      • 첫 번째 토큰이 solved인 경우
        • TreeSet에서 StringTokenizer의 다음 값을 int로 변환해 제거
      • 첫 번째 토큰이 recommend인 경우
        • int 변수 x에 StringTokenizer의 다음 값을 int로 변환해 대입
        • 만약 x가 1과 같다면
          • StringBuffer에 TreeSet의 첫 번째 값을 추가하고 “\n”을 추가해 줄바꿈
            • 난이도가 가장 높은 문제의 번호를 추가
        • 그게 아니라면
          • StringBuffer에 TreeSet의 마지막 값을 추가하고 “\n”을 추가해 줄바꿈
            • 난이도가 가장 낮은 문제의 번호를 추가
  • for문이 종료되면 StringBuffer를 출력
profile
공부 중인 신입 백엔드 개발자입니다

0개의 댓글