Java/코딩테스트

프로그래머스 - 단속카메라, 백준 13549, 5427

Bubbles 2023. 11. 10. 02:28

🚨 프로그래머스 : 단속카메라

https://school.programmers.co.kr/learn/courses/30/lessons/42884

 

프로그래머스

코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.

programmers.co.kr

 

🚨그리디 알고리즘 문제

 

🚨진입 / 진출 지점에서 만난 것도 만난 것으로 인정하므로 구간 끝에 카메라를 설치한다고 생각하면 된다. 

🚨여기서 진입 지점으로 정렬할지 진출 지점으로 정렬할지 헷갈렸는데 진출 시점으로 정렬해야 한다. 첫 구간이 아주 길다면 내부 구간이 다 무시되기 때문이다. 

 

🚨그림 설명

 

🚨전체코드

참고로 pivot은 이 구간의 최솟값이 -30000이라 -30001로 초기화하였다. 

import java.util.*;
class Solution {
    public int solution(int[][] routes) {
        PriorityQueue<Route> queue = new PriorityQueue<>((o1, o2) -> o1.end - o2.end);
        
        for (int[] route : routes) {
            queue.add(new Route(route[0], route[1]));
        }
        
        int answer = 0;
        int pivot = -30001;
        while (!queue.isEmpty()) {
            Route route = queue.poll();
            if (route.start > pivot) {
                pivot = route.end;
                answer++;
            }
        }
        return answer;
    }
    
    class Route {
        int start;
        int end;
        Route(int start, int end) {
            this.start = start;
            this.end = end;
        }
    }
}

 

 


 

 

🛝 백준 13549 : 숨바꼭질 3

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

 

13549번: 숨바꼭질 3

수빈이는 동생과 숨바꼭질을 하고 있다. 수빈이는 현재 점 N(0 ≤ N ≤ 100,000)에 있고, 동생은 점 K(0 ≤ K ≤ 100,000)에 있다. 수빈이는 걷거나 순간이동을 할 수 있다. 만약, 수빈이의 위치가 X일 때

www.acmicpc.net

 

🛝 BFS 알고리즘 문제

 

🛝 수빈 위치와 동생 위치가 같다면 바로 0 출력해주고 끝난다. 

🛝 방문 배열에 방문 처리 하고, 최단 시간 찾는 것이므로 BFS로 풀면 된다.

🛝 순간이동 한 경우 / 걸은 경우 시간은 다르게 표현해줘야 하며, 배열의 인덱스를 넘어가지 않도록 if 조건 분기만 잘 나누어주면 어렵지 않게 풀 수 있다 

 

🛝 전체코드

import java.util.LinkedList;
import java.util.Queue;
import java.util.Scanner;

public class p13549 {
    public static void main(String[] args) {
        int[] arr = new int[100001];
        boolean[] visited = new boolean[100001];
        Scanner sc = new Scanner(System.in);
        Queue<Integer> queue = new LinkedList<>();

        int n = sc.nextInt();
        int k = sc.nextInt();
        queue.add(n);
        visited[n] = true;
        arr[n] = 1;
        if (n == k) {
            System.out.println(0);
            return;
        }

        while (!queue.isEmpty()) {
            int poll = queue.poll();
            if (poll == k) {
                System.out.println(arr[poll] -1);
                break;
            }

            if (poll <= 50000 && !visited[poll*2]) {
                arr[poll*2] = arr[poll];
                visited[poll*2] = true;
                queue.add(poll*2);
            }
            if (poll > 0 && !visited[poll-1]) {
                arr[poll-1] = arr[poll] + 1;
                visited[poll-1] = true;
                queue.add(poll-1);
            }
            if (poll < 100000 && !visited[poll+1]) {
                arr[poll+1] = arr[poll] + 1;
                visited[poll+1] = true;
                queue.add(poll+1);
            }

        }
    }
}

 

 


 

 

 

🔥 백준 5427 : 불

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

 

5427번: 불

상근이는 빈 공간과 벽으로 이루어진 건물에 갇혀있다. 건물의 일부에는 불이 났고, 상근이는 출구를 향해 뛰고 있다. 매 초마다, 불은 동서남북 방향으로 인접한 빈 공간으로 퍼져나간다. 벽에

www.acmicpc.net

 

🔥백준 4179번 - 불! 과 느낌표 하나 차이로 다른 문제가 있어서 풀어봤다. 

🔥동일하게 BFS 문제이다. 

 

🔥불이 아예 없는 경우(fires.isEmpty())인 경우 불 BFS 돌리지 않도록 하기 

🔥불이 있어도 불 자체가 벽으로 둘러쌓여서 못 퍼지는 경우 있을 수도 있다. 이 경우 visitied 값이 0이라 탈출 못한걸로 판정나는 실수가 있었는데, 그래서 마지막 정답 비교조건에서 불길이 아예 닿지 않았거나, 나의 도착시간이 불보다 빠른 경우에 정답을 갱신하도록 만들었다. 

🔥이 2가지 예외처리만 잘 해준다면 이전에 풀었던 문제와 유사한 문제였다. 

 

🔥전체코드

import java.io.*;
import java.util.*;
public class p5427 {
    private static char[][] map;
    private static int[][] visited;
    private static int[] dirX = { 0, 0, 1, -1 }; // 동서남북
    private static int[] dirY = { 1, -1, 0, 0 };
    private static int row, col;
    private static Pos me;
    private static List<Pos> fires;

    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        int n = Integer.parseInt(br.readLine());

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

            map = new char[row][col];
            visited = new int[row][col];
            fires = new ArrayList<>();

            for (int j = 0; j < row; j++) {
                String line = br.readLine();
                for (int k = 0; k < col; k++) {
                    map[j][k] = line.charAt(k);
                    if (map[j][k] == '@') {
                        me = new Pos(j, k);
                    }
                    else if (map[j][k] == '*') {
                        fires.add(new Pos(j, k));
                    }
                }
            }

            int answer = BFS();
            if (answer == Integer.MAX_VALUE) {
                System.out.println("IMPOSSIBLE");
            } else {
                System.out.println(answer);
            }
        }

    }


    private static int BFS() {
        int answer = Integer.MAX_VALUE;
        Map<Pos, Integer> time = new HashMap<>();
        Queue<Pos> queue = new LinkedList<>();

        queue.add(me);
        visited[me.x][me.y] = 1;
        while (!queue.isEmpty()) {
            Pos poll = queue.poll();
            for (int i = 0; i < 4; i++) {
                int nextX = poll.x + dirX[i];
                int nextY = poll.y + dirY[i];

                if (nextX < 0|| nextX >= row || nextY < 0 || nextY >= col) {
                    time.put(new Pos(poll.x, poll.y), visited[poll.x][poll.y]);
                    continue;
                }

                if (map[nextX][nextY] != '.') {
                    continue;
                }

                if (visited[nextX][nextY] != 0) {
                    continue;
                }

                queue.add(new Pos(nextX, nextY));
                visited[nextX][nextY] = visited[poll.x][poll.y] + 1;
            }
        }

        if (fires.isEmpty()) {
            for (Integer i : time.values()) {
                answer = Math.min(answer, i);
            }
            return answer;
        }

        // 불 퍼트리기
        queue = new LinkedList<>();
        visited = new int[row][col];
        queue.addAll(fires);
        for (Pos p : fires) {
            visited[p.x][p.y] = 1;
        }


        while (!queue.isEmpty()) {
            Pos poll = queue.poll();
            for (int i = 0; i < 4; i++) {
                int nextX = poll.x + dirX[i];
                int nextY = poll.y + dirY[i];

                if (nextX < 0 || nextX >= row || nextY < 0 || nextY >= col) {
                    continue;
                }

                if (map[nextX][nextY] == '#') {
                    continue;
                }

                if (visited[nextX][nextY] != 0) {
                    continue;
                }

                queue.add(new Pos(nextX, nextY));
                visited[nextX][nextY] = visited[poll.x][poll.y] + 1;
            }
        }

        for (Pos pos : time.keySet()) {
            if (visited[pos.x][pos.y] == 0 || time.get(pos) < visited[pos.x][pos.y]) {
                answer = Math.min(answer, time.get(pos));
            }
        }


        return answer;
    }

    private static class Pos {
        int x;
        int y;

        public Pos (int x, int y) {
            this.x = x;
            this.y = y;
        }
    }
}