모각코

6회차 결과

냥냥체뤼 2023. 8. 14. 11:35

후기

 

숨바꼭질3이라는 문제를 해결했다. 두 가지 방법으로 해결할 수 있었다. 처음에 시도할 때 순간이동이라는 것을 우선 고려한다는 것을 잘 생각을 못해서 꽤 오려 걸렸다. 우선순위가 되는 것을 큐의 앞에 넣어야 한다는 것을 알고나서 해결할 수 있었다. 이번 주는 BFS문제를 많이 연습했지만, 이번 문제를 통해 특히 좋은 경험을 할 수 있었다.

 

 

 

방법1

(방법1): 큐의 특징을 좀 더 잘 이해하고
순간이동한다는 것을 큐와 연관지어 잘 생각했더라면 좋았을 것 같다.
public class Main{
    public static int limit = 100001;
    public static int N;
    public static int K;
    public static Queue<Integer> q = new LinkedList<>();
    public static int[] map;

    public static void main(String[] args) throws IOException{
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        String[] line = br.readLine().split(" ");
        N = Integer.parseInt(line[0]);
        K = Integer.parseInt(line[1]);

        map = new int[limit + 2];
        map[N] = 1;
        q.add(N);
        teleport(N);
        while(map[K] == 0){
            int now = q.poll();
            int[] nextPosition = {now+1, now-1};
            for(int position : nextPosition){
                if(position < 0 || position >= limit) continue;
                if(map[position] != 0) continue;
                map[position] = map[now] + 1;
                q.add(position);
                teleport(position);
            }
        }
        System.out.println(map[K]-1);
    }
    public static void teleport(int num){
        int tmp = num;
        if (tmp == 0) return;
        while(tmp < limit && map[K] == 0){
            if(map[tmp] == 0){
                map[tmp] = map[num];
                q.add(tmp);
                if(tmp == K) return;
            }
            tmp *= 2;
        }
    }
}

 

방법2

(방법2)
// 0-1 BFS
public class Main{
    public static int limit = 200002;
    public static int N;
    public static int K;

    public static void main(String[] args) throws IOException{
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        String[] line = br.readLine().split(" ");
        N = Integer.parseInt(line[0]);
        K = Integer.parseInt(line[1]);
        int limit = 200000;
        int[] map = new int[limit];
        Arrays.fill(map, -1);
        Deque<Integer> dq = new LinkedList<>(); // ★★★
        map[N] = 0; // ★★★
        dq.addLast(N);
        // 0-1 BFS 알고리즘은 O(V + E)의 선형시간이다.
        // 우선순위인 것을 dq의 앞에 넣고(가중치0), 우선순위 아닌 건 뒤에 넣는다(가중치1)
        // 그래서 순간이동은 dq의 앞에, 일반 +-1이동은 dq의 뒤에 넣는다.
        // 다익스트라처럼 큐에는 오직 이전 정점을 통해 최단 거리가 줄어든 정점만 큐에 삽입한다.
        // 그래서 순간이동한 것들이 바로 그 최단거리가 줄어든 상황이며, 그래서 큐의 앞에 삽입함
        // 큐는 항상 시작점으로부터의 거리에 대해 정렬된 상태임.
        // 그래서 map[index]에는 항상 최단거리가 기록되며,
        // 이미 한번 기록된 이력이 있어 -1값(초기화값)을 벗어나면, 패스함.
        // 그래서 O(V + E)라는 것임. 
        while(!dq.isEmpty()){
            int now = dq.pollFirst();
            if(2*now < limit && map[2*now] == -1){
                map[2*now] = map[now];
                dq.addFirst(2*now);
            }
            int[] nextPosition = {now-1, now+1};
            for(int next : nextPosition){
                if(next < 0 || next >= limit || map[next] != -1) continue;
                map[next] = map[now] + 1;
                dq.addLast(next);
            }
        }
        System.out.println(map[K]);
    }
}
반응형