티스토리 뷰

Algorithm

백준_연구소 3_17142

Young_J 2020. 12. 29. 23:02

//알고리즘

1. 탐색

 -> 최소시간을 출력하므로 bfs탐색

 

2. 활성화 시킬 바이러스 선택

 -> 바이러스를 ArrayList로 받고 선택할 바이러스를 조합으로 구현

 

3. 선택된 바이러스를 큐에넣고 bfs탐색 시작

 -> 최소시간이기 때문에 우선순위큐 사용

 -> 활성 바이러스가 비활성 바이러스가 있는 칸으로 가면 비활성 바이러스가 활성으로 변한다라는 조건이 있어서 탐색 중 비활성화된 바이러스에 도달한다면 현재의 시간+1 값으로 세팅해 큐에 다시 넣음 

 -> bfs가 끝나면 바이러스가 안 퍼진 곳이 있는 지 확인 후 정답 출력

 

더보기
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.PriorityQueue;
import java.util.StringTokenizer;

public class 연구소3_17142 {

	static int N, M, map[][], ans = Integer.MAX_VALUE;
	static int[] dr = { 1, -1, 0, 0 };
	static int[] dc = { 0, 0, 1, -1 };
	static boolean v[];
	static ArrayList<Point> virus, s_virus;
	static PriorityQueue<Point> q = new PriorityQueue<Point>();

	static class Point implements Comparable<Point> {
		int r, c, time;

		public Point(int r, int c, int time) {
			super();
			this.r = r;
			this.c = c;
			this.time = time;
		}

		@Override
		public int compareTo(Point o) {
			// TODO Auto-generated method stub
			return Integer.compare(this.time, o.time);
		}

	}

	public static void main(String[] args) throws IOException {

		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		StringTokenizer st = new StringTokenizer(br.readLine());

		N = Integer.parseInt(st.nextToken());
		M = Integer.parseInt(st.nextToken());

		map = new int[N][N];
		virus = new ArrayList<Point>();

		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 Point(i, j, 1));
			}
		}

		v = new boolean[virus.size()];
		// 알고리즘
		combination(0, 0);

		System.out.println(ans == Integer.MAX_VALUE ? -1 : ans);

	}

	private static void combination(int idx, int start) {
		if (idx == M) {
			bfs(v);
			return;
		}

		for (int i = start; i < virus.size(); i++) {
			v[i] = true;
			combination(idx + 1, i + 1);
			v[i] = false;
		}
	}

	private static void bfs(boolean[] v) {
		q.clear();
		Point p = null;
		boolean check[][] = new boolean[N][N];
		int[][] nMap = new int[N][N];
		for (int i = 0; i < v.length; i++) {
			if (v[i]) {
				p = virus.get(i);
				check[p.r][p.c] = true;
				q.add(new Point(p.r, p.c, p.time));
			}
		}

		Point virus = null;
		int max = 0;
		while (!q.isEmpty()) {
			virus = q.poll();

			if (max > ans)
				return;

			for (int k = 0; k < 4; k++) {
				int nr = virus.r + dr[k];
				int nc = virus.c + dc[k];

				if (nr < 0 || nc < 0 || nr >= N || nc >= N || check[nr][nc])
					continue;
				if (map[nr][nc] == 1) continue; // 벽일 경우
				if (map[nr][nc] == 2) {
					check[nr][nc] = true;
					q.add(new Point(nr, nc, virus.time+1));
					continue;
				}
				

				nMap[nr][nc] = virus.time;
				if (max < virus.time)
					max = virus.time;
				check[nr][nc] = true;
				q.add(new Point(nr, nc, virus.time + 1));
			}

		}
		for (int i = 0; i < nMap.length; i++) {
			for (int j = 0; j < nMap.length; j++) {
				if (map[i][j] == 0 && nMap[i][j] == 0)
					return;
			}
		}
		ans = max;

	}

}

 

※ 예외 처리만 잘 해주면 기본적인 bfs코드에서 조금반 변형하면 됨. 

'Algorithm' 카테고리의 다른 글

프로그래머스_카펫  (0) 2020.12.31
프로그래머스_소수 찾기  (0) 2020.12.30
백준_방 번호_1475  (0) 2020.12.28
백준_탈출_3055  (0) 2020.12.27
백준_패션왕 신한빈_9375  (0) 2020.12.25
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
TAG more
«   2025/02   »
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
글 보관함