|
| 1 | +import java.io.*; |
| 2 | +import java.util.*; |
| 3 | + |
| 4 | +public class Main { |
| 5 | + |
| 6 | + static int N, M; |
| 7 | + static int[][] g; |
| 8 | + static int[] dx = {-1, 1, 0, 0}; |
| 9 | + static int[] dy = {0, 0, -1, 1}; |
| 10 | + static boolean[][] visited; |
| 11 | + static int rCnt; |
| 12 | + static class Bomb implements Comparable<Bomb> { |
| 13 | + int x, y, color; |
| 14 | + |
| 15 | + public Bomb(int x, int y, int color) { |
| 16 | + super(); |
| 17 | + this.x = x; |
| 18 | + this.y = y; |
| 19 | + this.color = color; |
| 20 | + } |
| 21 | + |
| 22 | + @Override |
| 23 | + public int compareTo(Bomb other) { |
| 24 | + if(this.x == other.x) { |
| 25 | + // 2) ์ด์ด ์์ ์ |
| 26 | + return this.y - other.y; |
| 27 | + } |
| 28 | + // 1) ํ์ด ํฐ ์ |
| 29 | + return other.x - this.x; |
| 30 | + } |
| 31 | + |
| 32 | + @Override |
| 33 | + public String toString() { |
| 34 | + return "Bomb [x=" + x + ", y=" + y + ", color=" + color + "]"; |
| 35 | + } |
| 36 | + |
| 37 | + } |
| 38 | + |
| 39 | + public static void main(String[] args) throws IOException { |
| 40 | + BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); |
| 41 | + StringTokenizer st = new StringTokenizer(br.readLine()); |
| 42 | + |
| 43 | + N = Integer.parseInt(st.nextToken()); |
| 44 | + M = Integer.parseInt(st.nextToken()); |
| 45 | + |
| 46 | + g = new int[N][N]; |
| 47 | + for(int i=0; i<N; i++) { |
| 48 | + st = new StringTokenizer(br.readLine()); |
| 49 | + for(int j=0; j<N; j++) { |
| 50 | + g[i][j] = Integer.parseInt(st.nextToken()); |
| 51 | + } |
| 52 | + } |
| 53 | + |
| 54 | + int ans = 0; |
| 55 | + while(true) { |
| 56 | + // 1) ํญํ ๋ฌถ์ ์ฐพ๊ธฐ |
| 57 | + List<Bomb> bList = findBundle(); |
| 58 | + |
| 59 | + // ๋์ด์ ํญํ ๋ฌถ์์ด ์์ผ๋ฉด ์ข
๋ฃ |
| 60 | + if(bList.size() == 0) break; |
| 61 | + |
| 62 | + // ํญํ ๋ฌถ์ ์ ์ ๊ณ์ฐ |
| 63 | + int c = bList.size(); |
| 64 | + ans += (c*c); |
| 65 | + |
| 66 | + // 2) ํญํ ์ ๊ฑฐ & ์ค๋ ฅ ์์ฉ |
| 67 | + removeBomb(bList); |
| 68 | + |
| 69 | + setGravity(); |
| 70 | + |
| 71 | + // 3) ๋ฐ์๊ณ 90 ํ์ |
| 72 | + rotate(); |
| 73 | + |
| 74 | + // 4) ์ค๋ ฅ ์์ฉ |
| 75 | + setGravity(); |
| 76 | + |
| 77 | + } |
| 78 | + System.out.println(ans); |
| 79 | + |
| 80 | + } |
| 81 | + public static void print(int[][] a) { |
| 82 | + for(int i=0; i<g.length; i++) { |
| 83 | + System.out.println(Arrays.toString(g[i])); |
| 84 | + } |
| 85 | + System.out.println(); |
| 86 | + } |
| 87 | + public static boolean inRange(int x, int y) { |
| 88 | + return x>=0 && x<N && y>=0 && y<N; |
| 89 | + } |
| 90 | + public static List<Bomb> bfs(Bomb start) { |
| 91 | + Queue<Bomb> q = new LinkedList<>(); |
| 92 | + List<Bomb> aList = new ArrayList<>(); |
| 93 | + |
| 94 | + visited[start.x][start.y] = true; |
| 95 | + q.add(start); |
| 96 | + aList.add(start); |
| 97 | + |
| 98 | + // ๋นจ๊ฐ ํญํ ๋ฆฌ์คํธ |
| 99 | + List<Bomb> rList = new ArrayList<>(); |
| 100 | + |
| 101 | + while(!q.isEmpty()) { |
| 102 | + Bomb now = q.poll(); |
| 103 | + |
| 104 | + for(int i=0; i<4; i++) { |
| 105 | + int nx = now.x + dx[i]; |
| 106 | + int ny = now.y + dy[i]; |
| 107 | + |
| 108 | + if(!inRange(nx, ny)) continue; |
| 109 | + if(visited[nx][ny]) continue; |
| 110 | + if(g[nx][ny] != 0 && g[nx][ny] != start.color) continue; |
| 111 | + |
| 112 | + Bomb next = new Bomb(nx, ny, g[nx][ny]); |
| 113 | + if(g[nx][ny] == 0) { |
| 114 | + rList.add(next); |
| 115 | + } |
| 116 | + |
| 117 | + visited[nx][ny] = true; |
| 118 | + q.add(next); |
| 119 | + aList.add(next); |
| 120 | + } |
| 121 | + } |
| 122 | + |
| 123 | + rCnt = rList.size(); |
| 124 | + // ๋นจ๊ฐ ํญํ๋ค visited ์์๋ณต๊ท |
| 125 | + for(Bomb r: rList) { |
| 126 | + visited[r.x][r.y] = false; |
| 127 | + } |
| 128 | + |
| 129 | + if(aList.size() <= 1) { |
| 130 | + return new ArrayList<>(); |
| 131 | + } |
| 132 | + // ์ฐ์ ์์์ ๋ง๊ฒ ์ ๋ ฌ ํ ๋ฐํ |
| 133 | + Collections.sort(aList); |
| 134 | + return aList; |
| 135 | + |
| 136 | + } |
| 137 | + public static List<Bomb> findBundle() { |
| 138 | + // ๊ธฐ์ค์ ์ฐ์ ์์ ํ (ํฌ๊ธฐ->๋นจ๊ฐํญํ->ํ->์ด) |
| 139 | + PriorityQueue<int[]> pq = new PriorityQueue<>(new Comparator<int[]>() { |
| 140 | + @Override |
| 141 | + public int compare(int[] o1, int[] o2) { |
| 142 | + if(o1[0] == o2[0]) { |
| 143 | + if(o1[1] == o2[1]) { |
| 144 | + if(o1[2] == o2[2]) { |
| 145 | + // 4) ์ด์ด ์์ ์ |
| 146 | + return o1[3] - o2[3]; |
| 147 | + } |
| 148 | + // 3) ํ์ด ํฐ ์ |
| 149 | + return o2[2] - o1[2]; |
| 150 | + } |
| 151 | + // 2) ๋นจ๊ฐ ํญํ์ ๊ฐ์๊ฐ ์ ์ ์ |
| 152 | + return o1[1] - o2[1]; |
| 153 | + } |
| 154 | + // 1) ๋ฌถ์ ํฌ๊ธฐ๊ฐ ํฐ ์ |
| 155 | + return o2[0] - o1[0]; |
| 156 | + } |
| 157 | + }); |
| 158 | + // ๊ธฐ์ค์ ์ ์์น์ ํญํ ๋ฌถ์ ์ ์ฅ ํด์ฌ๋งต |
| 159 | + Map<Integer, List<Bomb>> tMap = new HashMap<>(); |
| 160 | + visited = new boolean[N][N]; |
| 161 | + for(int i=0; i<N; i++) { |
| 162 | + for(int j=0; j<N; j++) { |
| 163 | + // ๋นจ๊ฐ(0), ๋(-1), ๋น์นธ(-2) ์ ์ธ ํญํ๋ค์ด ๋์ |
| 164 | + if(g[i][j] > 0 && !visited[i][j]) { |
| 165 | + rCnt = 0; |
| 166 | + List<Bomb> bList = bfs(new Bomb(i, j, g[i][j])); |
| 167 | + |
| 168 | + if(bList.size() == 0) continue; |
| 169 | + |
| 170 | + Bomb center = bList.get(0); |
| 171 | + int cNum = center.x*N + center.y; |
| 172 | + if(tMap.getOrDefault(cNum, new ArrayList<>()).size() > bList.size()) { |
| 173 | + continue; |
| 174 | + } |
| 175 | + tMap.put(cNum, bList); |
| 176 | + pq.add(new int[] {bList.size(), rCnt, center.x, center.y}); |
| 177 | + } |
| 178 | + } |
| 179 | + } |
| 180 | + // pq๊ฐ ๋น์ด์๋ค๋ฉด ๋ง์กฑํ๋ ํญํ ๋ฌถ์๋ค ์์ |
| 181 | + if(pq.size() == 0) return new ArrayList<>(); |
| 182 | + // ๊ฐ์ฅ ์ฐ์ ์์๊ฐ ๋์ ๊ธฐ์ค์ |
| 183 | + int[] target = pq.poll(); |
| 184 | + return tMap.get(target[2]*N + target[3]); |
| 185 | + |
| 186 | + } |
| 187 | + public static void removeBomb(List<Bomb> bList) { |
| 188 | + // -2 : ๋น์นธ |
| 189 | + for(Bomb b: bList) { |
| 190 | + g[b.x][b.y] = -2; |
| 191 | + } |
| 192 | + } |
| 193 | + public static void setGravity() { |
| 194 | + for(int y=0; y<N; y++) { |
| 195 | + for(int x=N-1; x>=0; x--) { |
| 196 | + if(g[x][y] < 0) continue; |
| 197 | + |
| 198 | + // ํญํ |
| 199 | + int color = g[x][y]; |
| 200 | + g[x][y] = -2; |
| 201 | + int t = x; |
| 202 | + while(t < N) { |
| 203 | + if(t+1 == N || g[t+1][y] != -2) break; |
| 204 | + t++; |
| 205 | + } |
| 206 | + g[t][y] = color; |
| 207 | + } |
| 208 | + } |
| 209 | + } |
| 210 | + public static void rotate() { |
| 211 | + int[][] t = new int[N][N]; |
| 212 | + |
| 213 | + for(int x=0; x<N; x++) { |
| 214 | + for(int y=0; y<N; y++) { |
| 215 | + int nx = N - y - 1; |
| 216 | + int ny = x; |
| 217 | + t[nx][ny] = g[x][y]; |
| 218 | + } |
| 219 | + } |
| 220 | + |
| 221 | + g = t; |
| 222 | + } |
| 223 | + |
| 224 | +} |
0 commit comments