Notice
Recent Posts
Recent Comments
Link
«   2025/07   »
1 2 3 4 5
6 7 8 9 10 11 12
13 14 15 16 17 18 19
20 21 22 23 24 25 26
27 28 29 30 31
Tags
more
Archives
Today
Total
관리 메뉴

be programmer

14442 : 벽 부수고 이동하기 2 - JAVA 본문

알고리즘/문제풀이

14442 : 벽 부수고 이동하기 2 - JAVA

mm______m 2024. 7. 16. 03:45

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

벽 부수고 이동하기 시리즈의 두번째 문제이다.

1은 1학년때 말기에 풀었기에 4년이 넘게 지난 지금, 아무런 기억이 나지 않아서 고민을 여러번 한 문제이다.

나는 기존 풀이를 참고하여 벽 뚫을 수 있는 횟수를 계산하는 배열을 추가했다. 벽을 부술수 없는 상태일 경우 더이상 벽을 부술수 없게 하는 장치가 필요했기 때문이다.  어떤 칸에 도달했을 때 나는 벽을 부술 수 있을 수도 있고, 그렇지 않을수도 있기 때문이다. 큐에 현재만의 최적 상태를 넣는다고 해서, 완전 최적상태를 찾을수 있음을 단언할 수 없다. 

 

핵심 로직은 다음과 같다. 잘 알고있듯 큐에 좌표와 거리, 브레이크 카운터를 저장하고, 브레이크 카운터가 차기 전까지는 벽을 부수고 이동할수 있게끔 코드를 짰다.

뚫을수 없을때는 큐에 아무것도 추가가 안된채로 반복문 초장으로 돌아간다.

            for(int i = 0; i < 4; i++){
                int mx = dx[i] + nd.x;
                int my = dy[i] + nd.y;
                if(mx < 0 || my < 0 || mx >= n || my >= m) continue;
                //안 막혔을 경우
                if(map[mx][my] == 0 && !check[mx][my][nd.bc]){
                    check[mx][my][nd.bc] = true;
                    q.add(new Node(mx, my, nd.dist+1, nd.bc));
                }
                //막힘
                else{
                    //뚫을수 있을때
                    if(nd.bc < k && !check[mx][my][nd.bc+1]){
                        check[mx][my][nd.bc+1] = true;
                        q.add(new Node(mx, my, nd.dist+1, nd.bc+1));
                    }
                }
            }

 

소스코드

import java.util.*;
import java.io.*;

public class Main {
    static int n, m, k, ans=-1;
    static int[][] map;
    static boolean[][][] check;
    static int[] dx = {0, 0, -1, 1};
    static int[] dy = {1, -1, 0, 0};
    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
        StringTokenizer st;

        st = new StringTokenizer(br.readLine());
        n = Integer.parseInt(st.nextToken());
        m = Integer.parseInt(st.nextToken());
        k = Integer.parseInt(st.nextToken());
        map = new int[n][m];
        check= new boolean[n][m][k+1];
        String s;
        for(int i = 0; i < n; i++){
            s = br.readLine();
            for(int j = 0; j < m; j++){
                map[i][j] = Integer.parseInt(String.valueOf(s.charAt(j)));
            }
        }
        bfs();
        bw.write(String.valueOf(ans));
        bw.flush();
        bw.close();
        br.close();
    }
    public static void bfs(){
        Queue<Node> q = new LinkedList<>();
        q.add(new Node(0, 0, 1, 0));
        check[0][0][0] = true;
        while(!q.isEmpty()){
            Node nd = q.poll();
            if(nd.x == n-1 && nd.y == m-1){
                ans = nd.dist;
                break;
            }
            for(int i = 0; i < 4; i++){
                int mx = dx[i] + nd.x;
                int my = dy[i] + nd.y;
                if(mx < 0 || my < 0 || mx >= n || my >= m) continue;
                //안 막혔을 경우
                if(map[mx][my] == 0 && !check[mx][my][nd.bc]){
                    check[mx][my][nd.bc] = true;
                    q.add(new Node(mx, my, nd.dist+1, nd.bc));
                }
                //막힘
                else{
                    //뚫을수 있을때
                    if(nd.bc < k && !check[mx][my][nd.bc+1]){
                        check[mx][my][nd.bc+1] = true;
                        q.add(new Node(mx, my, nd.dist+1, nd.bc+1));
                    }
                }
            }
        }
    }
    public static class Node{
        int x, y, dist, bc;
        Node(int x, int y, int dist, int bc){
            this.x = x;
            this.y = y;
            this.dist = dist;
            this.bc = bc;
        }
    }
}

'알고리즘 > 문제풀이' 카테고리의 다른 글

1946 : 신입 사원 - JAVA  (0) 2024.11.07
11057 : 오르막 수 - JAVA  (2) 2024.09.03
15993 : 1,2,3 더하기 8 - JAVA  (0) 2024.07.04
9184 : 신나는 함수 실행 - JAVA  (0) 2024.07.04
16719 : ZAOC - JAVA  (0) 2024.07.02