백준공부/java

[백준] 2206번 벽 부수고 이동하기 (gold 3

gomduri43 2023. 9. 21. 19:37

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

class Point{
    int x;
    int y;
    int broke;
    int l;
    public Point(int x, int y, int broke, int l){
        this.x=x;
        this.y=y;
        this.broke=broke;
        this.l=l;
    }
}
public class Main {
    static int[] numx={0,0,1,-1};
    static int[] numy={-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=new StringTokenizer(br.readLine());
        int n=Integer.valueOf(st.nextToken());
        int m=Integer.valueOf(st.nextToken());

        int[][] map=new int[n+1][m+1];
        for(int i=1; i<=n; i++){
            String a=br.readLine();
            for(int j=1; j<=m; j++){
                map[i][j]=a.charAt(j-1)-'0';
            }
        }

        Queue<Point> que =new LinkedList<>();
        map[1][1]=-1;
        que.offer(new Point(1,1,0,1));

        int answer=0;
        while(!que.isEmpty()){
            Point temp=que.poll();
            if(temp.x==m && temp.y==n){
                answer=temp.l;
                break;
            }

            for(int i=0; i<4; i++){
                int tx=temp.x+numx[i];
                int ty=temp.y+numy[i];

                if(tx<1 || tx>m || ty<1 || ty>n || map[ty][tx]==2){
                    continue;
                }
                if(map[ty][tx]==1 && temp.broke==0){
                    que.offer(new Point(tx,ty, 1, temp.l+1));
                }
                else if(map[ty][tx]!=0 && temp.broke==1){
                    continue;
                }
                else if(map[ty][tx]==-1 && temp.broke==0){
                    map[ty][tx]=2;
                    que.offer(new Point(tx,ty,temp.broke, temp.l+1));
                }
                else{
                    map[ty][tx]=-1;
                    que.offer(new Point(tx,ty, temp.broke, temp.l+1));
                }
            }
        }

        bw.write(answer==0 ? "-1" : answer+"");
        bw.flush();
    }
}

//생각한 아이디어 일단 벽을 부수면서 가면 그 길은 앵간하면 최소가 될 가능성 존재.
//일단 간 길은 -1로 표시한다. 하지만, 벽을 부순 기회를 사용하여 추후에 막힐 경우도 다분히 존재.
//벽을 부수고 간 애는 0의 가중치 간선으로만 이동가능
//하지만 벽을 한번도 안 부순 친구는 0이나 -1이로도 이동이 가능. 단 벽을 안부수고 이동할때는
//2로 표시 . 왜냐하면 이길은 다시 갈 일이 전혀 없음. 이렇게해서 중복, 왔던 길 재방문안하고,
//최대한 전진으로 나아가면서 파악. n,m에 도달하면 break는 동일.
//최소거리 이므로, 제일 빨리 도달하는애가 거리값이 가장 작은 최솟값이므로.