|
| 1 | +import java.util.Arrays; |
| 2 | +import java.util.Scanner; |
| 3 | + |
| 4 | +public class Main { |
| 5 | + static Solver practice2_d = new practice2_d(); |
| 6 | + static Solver arc074_d = new arc074_d(); |
| 7 | + static Solver abc193_f = new abc193_f(); |
| 8 | + |
| 9 | + public static void main(String[] args) { |
| 10 | + // practice2_d.run(); |
| 11 | + // arc074_d.run(); |
| 12 | + abc193_f.run(); |
| 13 | + } |
| 14 | +} |
| 15 | + |
| 16 | +abstract class Solver implements Runnable { public abstract void run(); } |
| 17 | + |
| 18 | +/** |
| 19 | + * @problem |
| 20 | + * AtCoder Library Practice Contest D - Maxflow |
| 21 | + * {@see https://atcoder.jp/contests/practice2/tasks/practice2_d} |
| 22 | + * @submission |
| 23 | + * {@see https://atcoder.jp/contests/practice2/submissions/20808482} |
| 24 | + */ |
| 25 | +class practice2_d extends Solver { |
| 26 | + public Answer solve(int n, int m, char[][] g) { |
| 27 | + MaxFlow mf = new MaxFlow(n * m + 2); |
| 28 | + int s = n * m; |
| 29 | + int t = s + 1; |
| 30 | + for (int i = 0; i < n; i++) { |
| 31 | + for (int j = 0; j < m; j++) { |
| 32 | + if (g[i][j] == '#') continue; |
| 33 | + if (((i ^ j) & 1) == 0) { |
| 34 | + mf.addEdge(s, i * m + j, 1); |
| 35 | + } else { |
| 36 | + mf.addEdge(i * m + j, t, 1); |
| 37 | + } |
| 38 | + } |
| 39 | + } |
| 40 | + for (int i = 0; i < n; i++) { |
| 41 | + for (int j = i & 1; j < m; j += 2) { |
| 42 | + if (g[i][j] == '#') continue; |
| 43 | + if (j - 1 >= 0 && g[i][j - 1] == '.') { |
| 44 | + mf.addEdge(i * m + j, i * m + (j - 1), 1); |
| 45 | + } |
| 46 | + if (j + 1 < m && g[i][j + 1] == '.') { |
| 47 | + mf.addEdge(i * m + j, i * m + (j + 1), 1); |
| 48 | + } |
| 49 | + if (i - 1 >= 0 && g[i - 1][j] == '.') { |
| 50 | + mf.addEdge(i * m + j, (i - 1) * m + j, 1); |
| 51 | + } |
| 52 | + if (i + 1 < n && g[i + 1][j] == '.') { |
| 53 | + mf.addEdge(i * m + j, (i + 1) * m + j, 1); |
| 54 | + } |
| 55 | + } |
| 56 | + } |
| 57 | + int ans = (int) mf.maxFlow(s, t); |
| 58 | + int cnt = 0; |
| 59 | + for (var e : mf.getEdges()) { |
| 60 | + if (e.flow == 0) continue; |
| 61 | + int u = e.from; |
| 62 | + int v = e.to; |
| 63 | + if (u == s || v == t) continue; |
| 64 | + int ui = u / m, uj = u % m; |
| 65 | + int vi = v / m, vj = v % m; |
| 66 | + if (g[ui][uj] != '.' || g[vi][vj] != '.') { |
| 67 | + throw new AssertionError(); |
| 68 | + } |
| 69 | + if (ui == vi) { |
| 70 | + if (uj + 1 == vj) { |
| 71 | + g[ui][uj] = '>'; |
| 72 | + g[vi][vj] = '<'; |
| 73 | + } else if (uj == vj + 1) { |
| 74 | + g[ui][uj] = '<'; |
| 75 | + g[vi][vj] = '>'; |
| 76 | + } else { |
| 77 | + throw new AssertionError(); |
| 78 | + } |
| 79 | + } else if (uj == vj) { |
| 80 | + if (ui + 1 == vi) { |
| 81 | + g[ui][uj] = 'v'; |
| 82 | + g[vi][vj] = '^'; |
| 83 | + } else if (ui == vi + 1) { |
| 84 | + g[ui][uj] = '^'; |
| 85 | + g[vi][vj] = 'v'; |
| 86 | + } else { |
| 87 | + throw new AssertionError(); |
| 88 | + } |
| 89 | + } else { |
| 90 | + throw new AssertionError(); |
| 91 | + } |
| 92 | + cnt++; |
| 93 | + } |
| 94 | + if (ans != cnt) throw new AssertionError(); |
| 95 | + return new Answer(ans, g); |
| 96 | + } |
| 97 | + |
| 98 | + static class Answer { |
| 99 | + final int c; |
| 100 | + final char[][] g; |
| 101 | + Answer(int c, char[][] g) { this.c = c; this.g = g; } |
| 102 | + @Override |
| 103 | + public String toString() { |
| 104 | + StringBuilder sb = new StringBuilder(); |
| 105 | + sb.append(c); |
| 106 | + for (char[] row : g) { |
| 107 | + sb.append('\n').append(row); |
| 108 | + } |
| 109 | + return sb.toString(); |
| 110 | + } |
| 111 | + } |
| 112 | + |
| 113 | + public void run() { |
| 114 | + Scanner sc = new Scanner(System.in); |
| 115 | + int n = Integer.parseInt(sc.next()); |
| 116 | + int m = Integer.parseInt(sc.next()); |
| 117 | + char[][] g = new char[n][]; |
| 118 | + Arrays.setAll(g, i -> sc.next().toCharArray()); |
| 119 | + sc.close(); |
| 120 | + System.out.println(solve(n, m, g)); |
| 121 | + } |
| 122 | +} |
| 123 | + |
| 124 | +/** |
| 125 | + * @problem |
| 126 | + * AtCoder Regular Contest 074 F - Lotus Leaves |
| 127 | + * {@see https://atcoder.jp/contests/arc074/tasks/arc074_d} |
| 128 | + * @submission |
| 129 | + * {@see https://atcoder.jp/contests/arc074/submissions/20808863} |
| 130 | + */ |
| 131 | +class arc074_d extends Solver { |
| 132 | + static final int INF = 1 << 20; |
| 133 | + public int solve(int h, int w, char[][] g) { |
| 134 | + int si = -1, sj = -1, ti = -1, tj = -1; |
| 135 | + boolean[][] grid = new boolean[h][w]; |
| 136 | + for (int i = 0; i < h; i++) { |
| 137 | + for (int j = 0; j < w; j++) { |
| 138 | + if (g[i][j] == 'S') { |
| 139 | + si = i; sj = j; |
| 140 | + grid[i][j] = true; |
| 141 | + } else if (g[i][j] == 'T') { |
| 142 | + ti = i; tj = j; |
| 143 | + grid[i][j] = true; |
| 144 | + } else if (g[i][j] == 'o') { |
| 145 | + grid[i][j] = true; |
| 146 | + } |
| 147 | + } |
| 148 | + } |
| 149 | + int s = h + w; |
| 150 | + int t = s + 1; |
| 151 | + MaxFlow mf = new MaxFlow(h + w + 2); |
| 152 | + mf.addEdge(s , si , INF); |
| 153 | + mf.addEdge(s , sj + h, INF); |
| 154 | + mf.addEdge(ti , t , INF); |
| 155 | + mf.addEdge(tj + h, t , INF); |
| 156 | + for (int i = 0; i < h; i++) { |
| 157 | + for (int j = 0; j < w; j++) { |
| 158 | + if (grid[i][j]) { |
| 159 | + mf.addEdge(i, j + h, 1); |
| 160 | + mf.addEdge(j + h, i, 1); |
| 161 | + } |
| 162 | + } |
| 163 | + } |
| 164 | + int flow = (int) mf.maxFlow(s, t); |
| 165 | + return flow >= INF ? -1 : flow; |
| 166 | + } |
| 167 | + |
| 168 | + public void run() { |
| 169 | + Scanner sc = new Scanner(System.in); |
| 170 | + int h = Integer.parseInt(sc.next()); |
| 171 | + int w = Integer.parseInt(sc.next()); |
| 172 | + char[][] g = new char[h][]; |
| 173 | + Arrays.setAll(g, i -> sc.next().toCharArray()); |
| 174 | + sc.close(); |
| 175 | + System.out.println(solve(h, w, g)); |
| 176 | + } |
| 177 | +} |
| 178 | + |
| 179 | +/** |
| 180 | + * @problem |
| 181 | + * AtCoder Beginner Contest 193 F - Zebraness |
| 182 | + * {@see https://atcoder.jp/contests/abc193/tasks/abc193_f} |
| 183 | + * @submission |
| 184 | + * {@see https://atcoder.jp/contests/abc193/submissions/20808965} |
| 185 | + */ |
| 186 | +class abc193_f extends Solver { |
| 187 | + static final int[] dx4 = {1, 0, -1, 0}; |
| 188 | + static final int[] dy4 = {0, 1, 0, -1}; |
| 189 | + |
| 190 | + public int solve(int n, char[][] c) { |
| 191 | + int[][] id = new int[n][n]; |
| 192 | + int cnt = 0; |
| 193 | + for (int i = 0; i < n; i++) { |
| 194 | + for (int j = 0; j < n; j++) { |
| 195 | + if (c[i][j] == '?') { |
| 196 | + id[i][j] = cnt++; |
| 197 | + } |
| 198 | + } |
| 199 | + } |
| 200 | + |
| 201 | + int ans = 0; |
| 202 | + for (int i = 0; i < n; i++) { |
| 203 | + for (int j = 0; j < n; j++) { |
| 204 | + if (i < n - 1) { |
| 205 | + if (c[i][j] == 'B' && c[i + 1][j] == 'W' || c[i][j] == 'W' && c[i + 1][j] == 'B') { |
| 206 | + ans++; |
| 207 | + } |
| 208 | + } |
| 209 | + if (j < n - 1) { |
| 210 | + if (c[i][j] == 'B' && c[i][j + 1] == 'W' || c[i][j] == 'W' && c[i][j + 1] == 'B') { |
| 211 | + ans++; |
| 212 | + } |
| 213 | + } |
| 214 | + } |
| 215 | + } |
| 216 | + MaxFlow mf = new MaxFlow(cnt + 2); |
| 217 | + int s = cnt, t = cnt + 1; |
| 218 | + for (int i = 0; i < n; i++) { |
| 219 | + for (int j = 0; j < n; j++) { |
| 220 | + if (c[i][j] == '?') { |
| 221 | + int b = 0, w = 0; |
| 222 | + for (int d = 0; d < 4; d++) { |
| 223 | + int ni = i + dx4[d]; |
| 224 | + int nj = j + dy4[d]; |
| 225 | + if (ni < 0 || ni >= n || nj < 0 || nj >= n) continue; |
| 226 | + if (c[ni][nj] == 'B') { |
| 227 | + b++; |
| 228 | + } else if (c[ni][nj] == 'W') { |
| 229 | + w++; |
| 230 | + } else if (d < 2) { |
| 231 | + mf.addEdge(id[i][j], id[ni][nj], 1); |
| 232 | + mf.addEdge(id[ni][nj], id[i][j], 1); |
| 233 | + ans++; |
| 234 | + } |
| 235 | + } |
| 236 | + mf.addEdge(id[i][j], t, (i + j) % 2 == 1 ? b : w); |
| 237 | + mf.addEdge(s, id[i][j], (i + j) % 2 == 1 ? w : b); |
| 238 | + ans += b + w; |
| 239 | + } |
| 240 | + } |
| 241 | + } |
| 242 | + return (int) (ans - mf.maxFlow(s, t)); |
| 243 | + } |
| 244 | + |
| 245 | + public void run() { |
| 246 | + Scanner sc = new Scanner(System.in); |
| 247 | + int n = Integer.parseInt(sc.next()); |
| 248 | + char[][] c = new char[n][]; |
| 249 | + Arrays.setAll(c, i -> sc.next().toCharArray()); |
| 250 | + sc.close(); |
| 251 | + System.out.println(solve(n, c)); |
| 252 | + } |
| 253 | +} |
0 commit comments