알고리즘

[백준/자바] #17836

룰루루 2025. 6. 15. 18:04

이전의 파이썬 풀이의 로직을 그대로 적용해봤는데, 중간에 자꾸 Fail이 났다. 결국 다른 풀이를 참고해서 풀었다. 아쉬운 마음에 풀었던 기록이라도 남겨본다. 

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


class Main {

    static class Item implements Comparable<Item> {
        int x;
        int y;
        int time;
        public Item(int x, int y, int time) {
            this.x = x;
            this.y = y;
            this.time = time;
        }

        @Override
        public int compareTo(Main.Item o) {
            if (this.time > o.time) {
                return 1;
            } else if (this.time < o.time) {
                return -1;
            }
            if (this.x > o.x) {
                return 1;
            } else if (this.x < o.x) {
                return -1;
            }
            if (this.y > o.y) {
                return 1;
            } else if (this.y < o.y) {
                return -1;
            }
            return 0;
        }
    }

    static int N, M, T;
    static int[][] graph;
    static boolean[][] visited;
    static int gramX, gramY;
    static PriorityQueue<Item> priorityQueue;
    static final int[] dx = {0, 0, 1, -1};
    static final int[] dy = {1, -1, 0, 0};
    static final int EMPTY = 0;
    static final int WALL = 1;
    static final int GRAM = 2;
    static final int INF = 100000;

    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        String[] input1 = br.readLine().split(" ");
        N = Integer.parseInt(input1[0]);
        M = Integer.parseInt(input1[1]);
        T = Integer.parseInt(input1[2]);
        graph = new int[N][M];
        visited = new boolean[N][M];
        priorityQueue = new PriorityQueue<>();
        
        for(int i=0; i<N; i++) {
            String[] input2 = br.readLine().split(" ");
            for(int j=0; j<M; j++) {
                graph[i][j] = Integer.parseInt(input2[j]);
                if (graph[i][j] == GRAM) {
                    gramX = i;
                    gramY = j;
                }
            }
        }
        br.close();

        int startToGram = find(gramX, gramY);
        int startToPrincess = find(N-1, M-1);
        int gramToPrincess = (N-1-gramX) + (M-1-gramY);

        if (startToGram == INF && startToPrincess == INF) {
            System.out.println("Fail");
        } else {
            int minDistance = Math.min(startToPrincess, startToGram + gramToPrincess);
            if (minDistance <= T) {
                System.out.println(minDistance);
            } else {
                System.out.println("Fail");
            }
        }
    }

    private static int find(int endX, int endY) {
        priorityQueue.add(new Item(0, 0, 0));
        visited[0][0] = true;
        while(!priorityQueue.isEmpty()) {
            Item item = priorityQueue.poll();
            if (item.x == endX && item.y == endY) {
                return item.time;
            }
            for(int k=0; k<4; k++) {
                int nx = item.x + dx[k];
                int ny = item.y + dy[k];
                if (0 <= nx && nx < N && 0 <= ny && ny < M && graph[nx][ny] != WALL && !visited[nx][ny]) {
                    priorityQueue.add(new Item(nx, ny, item.time + 1));
                    visited[nx][ny] = true;
                }
            }
        }
        return INF;
    }
}

 

참고한 풀이는 다음과 같다. 

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.LinkedList;
import java.util.Queue;
import java.util.StringTokenizer;

public class Main {
    static int N, M, T;
    static int answer = 10001;
    static int[][] map;
    static boolean[][] visited;
    static int[][] deltas = {{0, 1}, {1, 0}, {0, -1}, {-1, 0}};
    static Position sword;

    static class Position {
        int r, c;

        public Position(int r, int c) {
            this.r = r;
            this.c = c;
        }

    }

    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        StringTokenizer st = null;

        st = new StringTokenizer(br.readLine());
        N = Integer.parseInt(st.nextToken());
        M = Integer.parseInt(st.nextToken());
        T = Integer.parseInt(st.nextToken());

        map = new int[N][M];
        visited = new boolean[N][M];

        for (int i = 0; i < N; i++) {
            st = new StringTokenizer(br.readLine());
            for (int j = 0; j < M; j++) {
                map[i][j] = Integer.parseInt(st.nextToken());
                if (map[i][j] == 2) sword = new Position(i, j);
            }
        }

        bfs();

        System.out.println(answer > T ? "Fail" : answer);
    }

    static void bfs() {
        Queue<Position> queue = new LinkedList<>();
        queue.offer(new Position(0, 0));
        visited[0][0] = true;
        int count = -1;
        int size = 0;
        while (!queue.isEmpty()) {
            count++;
            size = queue.size();
            for (int step = 0; step < size; step++) {
                Position temp = queue.poll();

                if (temp.r == sword.r && temp.c == sword.c) {
                    answer = count + N - 1 - sword.r + M - 1 - sword.c;
                    continue;
                } else if (temp.r == N - 1 && temp.c == M - 1) {
                    answer = Math.min(answer, count);
                    return;
                }

                for (int i = 0; i < 4; i++) {
                    int nr = temp.r + deltas[i][0];
                    int nc = temp.c + deltas[i][1];

                    if (isIn(nr, nc) && !visited[nr][nc] && map[nr][nc] != 1) {
                        queue.offer(new Position(nr, nc));
                        visited[nr][nc] = true;

                    }
                }
            }
        }
    }

    static boolean isIn(int r, int c) {
        return r >= 0 && r < N && c >= 0 && c < M;
    }
}