Algorithm

[BOJ] 17142. 연구소 3

프로그래민 2020. 5. 29. 10:21
반응형

이문제는 조합을 이용하여 선택을 한다음 BFS를 사용하는 문제이다.

조합을 사용하여 바이러스의 위치를 뽑아주고, 그 다음 map에서 그위치를 활성화 시켜준 다음 BFS를 돌았다. 그 후 다시 map을 비활성화 시켜주는 작업을 하였다. 이 문제에서 현재 빈칸이 있는지 check를 할 때 맨처음에는 전체를 다보는 식으로 하였는데 시간초과의 결과를 얻었었다. 그래서 맨처음 입력받을때 빈칸의 갯수를 세어놓고 BFS를 돈다음 그 BFS를 도는 칸이 전체 빈칸의 갯수랑 같다면 true라고 생각해주고 답을 찾아주었다.

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
package boj2;
 
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.Queue;
import java.util.StringTokenizer;
 
public class Main_bj_17142_연구소3 {
    static int[] di= {-1,0,1,0};
    static int[] dj= {0,1,0,-1};
    
    static int N;
    static int R;
    
    static int[][] map;
    static boolean[][] visit;
    static Queue<Pos> queue;
    
    static boolean[] visitForComb;
    static Pos[] picks;
    static List<Pos> virus;
    static int V;
    
    static int answer;
    static int countZero;
    
    static class Pos{
        int i,j,time;
        Pos(int i,int j,int t){
            this.i=i;this.j=j;time=t;
        }
    }
    
    public static void main(String[] args) throws Exception {
        BufferedReader br= new BufferedReader(new InputStreamReader(System.in));
        StringTokenizer st = new StringTokenizer(br.readLine());
        N=Integer.parseInt(st.nextToken());
        R=Integer.parseInt(st.nextToken());
        
        map=new int[N][N];
        virus=new ArrayList<>();
        countZero=0;
        
        for(int i=0;i<N;i++) {
            st=new StringTokenizer(br.readLine());
            for(int j=0;j<N;j++) {
                map[i][j]=Integer.parseInt(st.nextToken());
                if(map[i][j]==2) {
                    virus.add(new Pos(i, j, 0));
                }else if(map[i][j]==0) {
                    countZero+=1;
                }
            }
        }
        
        picks=new Pos[R];
        V=virus.size();
        visitForComb=new boolean[V];
        
        queue=new LinkedList<>();
        answer=Integer.MAX_VALUE;
        comb(0,0);
        
        if(answer==Integer.MAX_VALUE)
            System.out.println(-1);
        else
            System.out.println(answer);
    }
    
    static void comb(int start,int depth) {
        if(depth==R) {
            bfs();
            return;
        }
        
        for(int i=start;i<V;i++) {
            if(visitForComb[i]==false) {
                visitForComb[i]=true;
                picks[depth]=virus.get(i);
                comb(i,depth+1);
                visitForComb[i]=false;
            }
        }
        
    }
    
    static void bfs() {
        int time=0;
        visit=new boolean[N][N];
        int count=0;
        for(Pos v : picks) {
            queue.offer(new Pos(v.i, v.j, 0));
            map[v.i][v.j]=-1;
        }
        
        while(!queue.isEmpty()) {
            Pos cur = queue.poll();
            if(map[cur.i][cur.j]==0) {    //빈칸일때만 체크
                count+=1;
                time=Math.max(time,cur.time);
            }
            
            for(int dir=0;dir<4;dir++) {
                int nextI=cur.i+di[dir];
                int nextJ=cur.j+dj[dir];
                
                if(nextI<0 || nextI>=|| nextJ<0 || nextJ>=N)
                    continue;
                
                if((map[nextI][nextJ]==0 || map[nextI][nextJ]==2&& visit[nextI][nextJ]==false) {
                    queue.offer(new Pos(nextI, nextJ, cur.time+1));
                    visit[nextI][nextJ]=true;
                }
            }
        }
        
        for(Pos v : picks) {
            map[v.i][v.j]=2;
        }
        
        if(countZero==count)
            answer=Math.min(answer, time);
    }
    
}
 
             
반응형

'Algorithm' 카테고리의 다른 글

[SWEA] 5215. 햄버거 다이어트  (0) 2020.05.29
[SWEA] 3234. 준환이의 양팔저울  (0) 2020.05.29
[BOJ] 1987. 알파벳  (0) 2020.05.27
[BOJ] 2580. 스도쿠  (0) 2020.05.27
[BOJ] 1248. 맞춰봐  (0) 2020.05.25