16234번: 인구 이동
좀더 간결하게 풀이해서 포스팅 (링크)
이전엔 방문체크를 다른 배열을 둬서 했는데 그런 것 없이 한번에 풀이하여서 좀더 깔끔한 풀이가 됨
풀이 개요
BFS나 DFS 와 같이 완전 탐색 이용해서 풀이하면 되는 문제.
나는 BFS를 사용하였고, BFS 두 번 돌리면 시간 초과가 일어나기에 한번 BFS를 돌릴 때, 인구 이동시 필요한 값들을 다 저장해야한다.
문제 풀이시 약간 헷갈려서 같은 역할을 하는 방문 체크를 위한 배열이 2개 있었는데 이 문제로 시간 초과도 떴다.
불필요한 부분은 제외하고 면밀한 풀이가 필수!
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 | import java.io.*; import java.util.*; class Main { static int N, L, R, marking; static boolean flag; static int[][] map , stamp; static boolean[][] marked; static ArrayList<Dot>[] arr; static int[] sum; static int max = 50 * 50 +1; public static void main(String[] args) throws Exception { BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); StringTokenizer st; st = new StringTokenizer(br.readLine()); N = Integer.parseInt(st.nextToken()); L = Integer.parseInt(st.nextToken()); // min R = Integer.parseInt(st.nextToken()); // max map = new int[N + 1][N + 1]; for (int i = 0; i < N; i++) { st = new StringTokenizer(br.readLine()); for (int j = 0; j < N; j++) { int temp = Integer.parseInt(st.nextToken()); map[i][j] = temp; } } int answer = 0; while (true) { marked = new boolean[N + 1][N + 1]; // 재탐색 안 하기 위함. flag = false; marking = 0; arr = new ArrayList[max]; sum = new int[max]; for(int i = 0; i < max; i++) { arr[i] = new ArrayList<>(); } //국경 확인 -> 전체를 확인하면서 국경을 파악한다. -> stamp를 남겨서 그룹화함. stamp = new int[N][N]; for (int i = 0; i < N; i++) { for (int j = 0; j < N; j++) { if(marked[i][j]) continue; boundary(new Dot(i, j)); marked[i][j] = true; } } if(!flag) break; answer++; //인구 이동 move(); } System.out.println(answer); } public static void move() { for(int i = 0; i < max; i++) { ArrayList<Dot> list = arr[i]; if(list.size() == 0) continue; int totalSum = sum[i]; int cal = totalSum/list.size(); for(Dot d : list) { map[d.row][d.col] = cal; } } } public static void boundary(Dot d) { Queue<Dot> queue = new LinkedList<Dot>(); int[][] dirs = { { 1, 0 }, { -1, 0 }, { 0, 1 }, { 0, -1 } }; queue.add(d); marked[d.row][d.col] = true; stamp[d.row][d.col] = ++marking; arr[stamp[d.row][d.col]].add(d); sum[stamp[d.row][d.col]] += map[d.row][d.col]; while (!queue.isEmpty()) { Dot cur = queue.poll(); for (int dir = 0; dir < 4; dir++) { int nextR = cur.row + dirs[dir][0]; int nextC = cur.col + dirs[dir][1]; if (nextR < 0 || nextC < 0 || nextR >= N || nextC >= N) continue; if (marked[nextR][nextC]) continue; int cal = Math.abs(map[cur.row][cur.col] - map[nextR][nextC]); if (cal < L || cal > R) continue; marked[nextR][nextC] = true; marked[nextR][nextC] = true; queue.add(new Dot(nextR, nextC)); arr[stamp[d.row][d.col]].add(new Dot(nextR, nextC)); sum[stamp[d.row][d.col]] += map[nextR][nextC]; flag = true; } } } } class Dot{ int row; int col; Dot(int row, int col){ this.row = row; this.col = col; } } | cs |
반응형
'알고리즘 문제 풀이 > BOJ' 카테고리의 다른 글
[backjoon]21610 마법사 상어와 비바라기 java (0) | 2021.10.01 |
---|---|
[backjoon]16236 아기상어 java (0) | 2021.09.30 |
[backjoon]12100 2048(easy) java (0) | 2021.09.15 |
[backjoon]3190 뱀 java (0) | 2021.09.09 |
[backjoon]15684 사다리 조작 java (0) | 2021.09.01 |