티스토리 뷰

Algorithm

백준_연구소_14502

Young_J 2021. 1. 23. 11:05

// 알고리즘

1. bfs

 

2. 3개의 벽을 세움

 -> v[N][M][N][M][N][M] 방문배열을 사용하여 중복계산제거

 

3. 벽을 세운 후 바이러스 퍼뜨리기

 -> 기존의 map을 입력할 때 바이러스 위치를 dq에 저장해놓고 bfs 시작 시 dq에 있는 모든값을 q에 집어넣고 시작

 -> 4방 탐색 

 -> 바이러스가 증식한 개수를 카운팅

 

4. 결과

 -> 기존의 맵을 입력받을 때 0의 개수 카운팅

 -> 0의 개수 -  증식한 개수 - 3(벽) 

 -> 최대값 

더보기
import java.util.*;
import java.io.*;

public class 연구소_14502 {

	static int N, M, ans,cnt_zero;
	static boolean v[][][][][][];
	static Queue<Point> dq;
	static Queue<Point> q = new LinkedList<>();
	static int[] dr = { -1, 1, 0, 0 };
	static int[] dc = { 0, 0, -1, 1 };

	static class Point {
		int r, c;

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

	}

	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());
		M = Integer.parseInt(st.nextToken());

		int[][] map = new int[N][M];
		v = new boolean[N][M][N][M][N][M];
		dq = new LinkedList<>();
		ans = 0;

		for (int i = 0; i < N; i++) {
			st = new StringTokenizer(br.readLine(), " ");
			for (int j = 0; j < M; j++) {
				map[i][j] = Integer.parseInt(st.nextToken());
				if (map[i][j] == 2)
					dq.add(new Point(i, j));
				if(map[i][j] == 0) {
					cnt_zero++;
				}
			}
		}

		cal(0, new int[6], map);
		System.out.println(ans);
//		print(map);

	}

	private static void cal(int idx, int[] vv, int[][] map) {
		if (idx == 6) {
			if (v[vv[0]][vv[1]][vv[2]][vv[3]][vv[4]][vv[5]] || v[vv[0]][vv[1]][vv[4]][vv[5]][vv[2]][vv[3]]
					|| v[vv[2]][vv[3]][vv[0]][vv[1]][vv[4]][vv[5]] || v[vv[4]][vv[5]][vv[0]][vv[1]][vv[2]][vv[3]]
					|| v[vv[2]][vv[3]][vv[4]][vv[5]][vv[0]][vv[1]] || v[vv[4]][vv[5]][vv[2]][vv[3]][vv[0]][vv[1]])
				return;

			v[vv[0]][vv[1]][vv[2]][vv[3]][vv[4]][vv[5]] = true;

			// 알고리즘
			bfs(map, new boolean[N][M]);

			return;
		}

		for (int i = 0; i < map.length; i++) {
			for (int j = 0; j < map[i].length; j++) {
				if (map[i][j] == 0) {
					map[i][j] = 1;
					vv[idx] = i;
					vv[idx + 1] = j;
					cal(idx + 2, vv, map);
					map[i][j] = 0;
					vv[idx] = 0;
					vv[idx + 1] = 0;
				}
			}
		}

	}

	private static void bfs(int[][] map, boolean[][] vvv) {
		q.clear();
		q.addAll(dq);
		
		Point p = null;
		int cnt = 0;
		while(!q.isEmpty()) {
			p = q.poll();
			vvv[p.r][p.c] = true;
			
			for (int k = 0; k < 4; k++) {
				int nr = p.r +  dr[k];
				int nc = p.c +  dc[k];
				
				if(nr < 0 || nc < 0 || nr >= N || nc >= M || vvv[nr][nc]) continue;
				if(map[nr][nc] == 1 || map[nr][nc] == 2) continue;
				vvv[nr][nc] = true;
				cnt ++;
				q.add(new Point(nr,nc));
				
			}
			
		}
		
		ans = Math.max(ans,cnt_zero - cnt-3);
		
		

	}


	private static void print(int[][] map) {
		for (int i = 0; i < N; i++) {
			for (int j = 0; j < M; j++) {
				System.out.print(map[i][j] + " ");
			}
			System.out.println();
		}

	}

}

 

※ N과 M 의 최대값이 8이고 최악의 경우라도 8C3 이기 때문에 완탐이 가능하다고 판단함.

  중복을 제거하기 위해 6차원 방문 배열을 사용했는데 중복을 생각안하고 8*7*6 을 해도 14만정도라 풀릴거같음.

  중복제거하는 방법이 지저분해서 다른 좋은방법을 찾아봐야겠음.

'Algorithm' 카테고리의 다른 글

백준_부분수열의 합_14225  (0) 2021.01.25
백준_프린터 큐_1966  (0) 2021.01.24
백준_스도미노쿠_4574  (0) 2021.01.20
백준_벽 부수고 이동하기 2_14442  (0) 2021.01.19
백준_구슬 탈출 2_13460  (0) 2021.01.18
공지사항
최근에 올라온 글
최근에 달린 댓글
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
글 보관함