알고리즘

[백준/Java] 23326 : 홍익 투어리스트

Stitchhhh 2025. 2. 20. 21:21

https://www.acmicpc.net/problem/23326

 

이 문제에서 원하는 것은 현재 도현이의 위치로부터 가장 가까운 명소를 찾는 것인데, 무조건 시계 방향으로만 돌아야만 합니다. 그래서 명소를 관리하기 위해 TreeSet 자료구조를 사용하였습니다. 그 이유로는 TreeSet에서는 X보다 큰 값 중에 가장 작은 값을 반환해주는 함수를 제공해주기 때문입니다.

 

의 경우에는 TreeSet에 저장되어 있으면 삭제하고, 저장되어 있지 않으면 추가를 합니다.

 

 2의 경우에는 도현이의 위치를 옮겨주어야 하는데 아무리 큰 수가 오더라고 결국 한 바퀴를 돌게 되면 제자리이기 때문에 나머지를 계산해 최종적으로 움직여야 하는 칸을 계산하고 크기를 넘을 경우 N으로 나누어 주면 됩니다.

 

 3의 경우에는 우선 명소가 있는 지 체크를 합니다. 그리고 현재 자리가 명소인지 확인을 하고 그래도 값이 없다면 현재 위치 기준으로 마지막 장소까지 명소를 확인하고 마지막으로 처음부터 현재 위치 기준으로 전 장소 까지 확인을 하면 됩니다.

그렇게 하면 전체 시간복잡도는 Q Log N이 되는데 이는 대략 1,800,000 이므로 시간제한에도 문제 없습니다.

 

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

public class Backjoon_23326_홍익_투어리스트 {
    public static void main(String[] args) throws IOException {

        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        StringTokenizer st = new StringTokenizer(br.readLine());
        StringBuilder sb = new StringBuilder();
        TreeSet<Integer> set = new TreeSet<>();

        int N = Integer.parseInt(st.nextToken());
        int Q = Integer.parseInt(st.nextToken());
        int pos = 1;

        st = new StringTokenizer(br.readLine());
        for(int i = 1 ; i <= N ;i++){
            int value = Integer.parseInt(st.nextToken());
            if(value == 1) {
                set.add(i);
            }
        }

        for(int i = 0; i < Q ; i++){
            st = new StringTokenizer(br.readLine());
            int number = Integer.parseInt(st.nextToken());

            if(number == 1){
                int idx = Integer.parseInt(st.nextToken());
                if(set.contains(idx)){
                    set.remove(idx);
                }else{
                    set.add(idx);
                }
            }else if(number == 2){
                int move = Integer.parseInt(st.nextToken()) % N;
                pos += move;
                if(pos > N){
                    pos %= N;
                }
            }else{
                if(set.isEmpty()){
                    sb.append("-1").append("\n");
                    continue;
                }

                if(set.contains(pos)){
                    sb.append(0).append("\n");
                    continue;
                }

                Integer front = set.higher(pos);
                Integer back = set.higher(0);

                if(front != null){
                    sb.append(front-pos).append("\n");
                }else{
                    sb.append(N-pos+back).append("\n");
                }
            }
        }
        System.out.println(sb);
    }
}