Algorithm

[BOJ] 5427. 불

프로그래민 2020. 3. 30. 10:47
반응형

BFS를 활용하는 문제이다.

이 문제의 경우 불(*)의 경우와 사람(@)의 경우가 있으므로 visit배열을 2차원 두개를 이용하기위해 3차원으로 선언하여 각 각 구분하여 문제를 접근하였다. 또한, 불길이 사람보다 먼저 번지기 때문에 일반적인 queue보단 deque를 이용하여 불길이 deque앞쪽에 들어가 있게 했다. 

위의 두가지 포인트가 기본적인 BFS 문제와 차이점을 보였던 문제이다.

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
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
package chap05;
 
 
public class Main_bj_5427_불 {
 
    static int[] di = {-1,0,1,0};
    static int[] dj = {0,1,0,-1};
    
    static int[][][] visit;
    static char[][] map;
    
    static int N,M;
    static int result;
 
    static Deque<Pos> deque;
    
    static class Pos{
        int i,j,sec,person;
        public Pos(int i,int j,int s,int p) {
            this.i=i;this.j=j;sec=s;person=p;
        }
    }
    
    public static void main(String[] args) throws Exception {
        BufferedReader br =new BufferedReader(new InputStreamReader(System.in));
        StringTokenizer st =null;
        
        int T=Integer.parseInt(br.readLine());
        
        
        for(int tc=1;tc<=T;tc++) {
            st= new StringTokenizer(br.readLine());
            M=Integer.parseInt(st.nextToken());
            N=Integer.parseInt(st.nextToken());
            
            map=new char[N][M];
            visit = new int[N][M][2];
            for(int i=0;i<N;i++) {
                for(int j=0;j<M;j++) {
                    visit[i][j][0]=-1;
                    visit[i][j][1]=-1;
                }
            }
            deque=new LinkedList<>();
            
            for(int i=0;i<N;i++) {
                String str= br.readLine();
                for(int j=0;j<M;j++) {
                    char ch = str.charAt(j);
                    map[i][j]=ch;
                    if(ch=='*') {
                        deque.addFirst(new Pos(i, j, 00));
                        visit[i][j][0]=0;
                    }else if(ch=='@') {
                        deque.addLast(new Pos(i, j, 01));
                        visit[i][j][1]=0;
                    }
                    
                }
            }
            
            result=-1;
            
            bfs();
            
//            for(int i=0;i<N;i++) {
//                for(int j=0;j<M;j++) {
//                    System.out.print(visit[i][j][0]+"\t");
//                }
//                System.out.println();
//            }
//            System.out.println();
//            for(int i=0;i<N;i++) {
//                for(int j=0;j<M;j++) {
//                    System.out.print(visit[i][j][1]+"\t");
//                }
//                System.out.println();
//            }
            
            
            if(result==-1)
                System.out.println("IMPOSSIBLE");
            else
                System.out.println(result);
            
            
            
        }
    }
    static void bfs() {
        while(!deque.isEmpty()) {
            Pos cur = deque.poll();
            
            for(int dir=0;dir<4;dir++) {
                int nextI = cur.i+di[dir];
                int nextJ = cur.j+dj[dir];
 
                if(cur.person==0) {        //불꽃인경우
                    
                    if(nextI<0 || nextI>=|| nextJ<0 || nextJ>=M)
                        continue;
                    
                    // . 이고 불꽃이 간적이 없으면 불꽃 바로 갱신
                    if(map[nextI][nextJ]=='.' && visit[nextI][nextJ][0]==-1) {
                        visit[nextI][nextJ][0]=cur.sec+1;
                        deque.offer(new Pos(nextI, nextJ, cur.sec+10));
                    }
                    
                    // @인데 
                    if(map[nextI][nextJ]=='@' && cur.sec+1 > visit[nextI][nextJ][1]) {
                        visit[nextI][nextJ][0]=cur.sec+1;
                        deque.offer(new Pos(nextI,nextJ,cur.sec+1,0));
                    }
                }else if(cur.person==1) {    //사람인 경우
                    
                    if(nextI<0 || nextI>=|| nextJ<0 || nextJ>=M) {
                        result=cur.sec+1;
                        return;
                    }
                    
                    //. 이고 내가 방문안한곳이면
                    if(map[nextI][nextJ]=='.' && visit[nextI][nextJ][1]==-1) {
                        if(visit[nextI][nextJ][0]==-1) {        //불길이 안간 곳
                            visit[nextI][nextJ][1]=cur.sec+1;
                            deque.offer(new Pos(nextI,nextJ,cur.sec+1,1));
                        }else if(visit[nextI][nextJ][0> cur.sec+1) {        //불길이 간곳
                            visit[nextI][nextJ][1]=cur.sec+1;
                            deque.offer(new Pos(nextI,nextJ,cur.sec+1,1));
                        }
                        
                    }
                    
                }
                
            }
            
        }
        
        
    }
}
 
http://colorscripter.com/info#e" target="_blank" style="color:#4f4f4ftext-decoration:none">Colored by Color Scripter
                                                   
반응형

'Algorithm' 카테고리의 다른 글

[BOJ] 13335. 트럭  (0) 2020.03.31
[BOJ] 14999. 주사위 굴리기  (0) 2020.03.31
[BOJ] 1182. 부분수열의 합  (0) 2020.03.30
[BOJ] 1707. 이분 그래프  (0) 2020.03.29
[BOJ] 9663. N-Queen  (0) 2020.03.27