Submission #49411
ソースコード
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 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 | import java.util.*; import java.io.*; class Main { static int [] dy = {1, 0, -1, 0}; static int [] dx = {0, 1, 0, -1}; public static void main(String[] args) { FastScanner sc = new FastScanner(System.in); PrintWriter out = new PrintWriter(System.out); int h, w, q; int com, x, y; char [][] mp; UnionFind uf = new UnionFind(1000 * 1000); h = Integer.parseInt(sc.next()); w = Integer.parseInt(sc.next()); q = Integer.parseInt(sc.next()); mp = new char [h][w]; for ( int i = 0; i < h; i++) { mp[i] = sc.next().toCharArray(); } for (y = 0; y < h; y++) { for (x = 0; x < w; x++) { if (mp[y][x] == '#' ) { for ( int i = 0; i < 4; i++) { int ny = y + dy[i]; int nx = x + dx[i]; if (ny >= 0 && ny < h && nx >= 0 && nx < w && mp[ny][nx] == '#' ) { uf.unite(encordIndex(x, y), encordIndex(nx, ny)); } } } } } for ( int i = 0; i < q; i++) { com = Integer.parseInt(sc.next()); y = Integer.parseInt(sc.next()); x = Integer.parseInt(sc.next()); x--; y--; if (com == 1) { if (mp[y][x] == '.' ) { out.println(0); } else { out.println(uf.groupSize(encordIndex(x, y))); } } else { mp[y][x] = '#' ; for ( int j = 0; j < 4; j++) { int ny = y + dy[j]; int nx = x + dx[j]; if (ny >= 0 && ny < h && nx >= 0 && nx < w && mp[ny][nx] == '#' ) { uf.unite(encordIndex(x, y), encordIndex(nx, ny)); } } } } out.flush(); } public static int encordIndex( int x, int y) { return y * 1000 + x; } } /** * @author ei1710 * @version 1.05 */ /** * 素集合データ構造.<br> * 各操作O(a(n))程度(a() はアッカーマン関数の逆関数) */ class UnionFind { /** * 添字の示すノードの親.<br> * 親がない = 自身が根のとき、-1 * (集合の大きさ)をもつ */ int [] parent; /** * 木の大きさ.<br> * あまり速くならなかった<br> * 計算量は O(log n) から O(a(n))くらいまで落ちるはずなのに */ int [] rank; /** nmemb個の要素からなる UnionFind */ public UnionFind( int nmemb) { parent = new int [nmemb]; rank = new int [nmemb]; Arrays.fill(parent, -1); Arrays.fill(rank, 0); } /** * 根を求める * @param x 根を求めるノードの番号 */ protected int root( int x) { if (parent[x] < 0) { return x; } parent[x] = root(parent[x]); return parent[x]; } /** ノードx, yが同じ集合であるかを確かめる */ public boolean isSameGroup( int x, int y) { return root(x) == root(y); } /** * ノードx, y を併合. * x, yがすでに同じ集合にあるときは何もしない */ public void unite( int x, int y) { x = root(x); y = root(y); if (x == y) { return ; } //小さい木を大きい方へマージ(木の高さを抑えられるので) if (rank[x] > rank[y]) { parent[x] += parent[y]; parent[y] = x; } else { parent[y] += parent[x]; parent[x] = y; if (rank[x] == rank[y]) { rank[y]++; } } return ; } /** グループの大きさ(=要素数)を調べる */ public int groupSize( int x) { return -1 * parent[root(x)]; } } class FastScanner { private int n; private long m; private int minus; private BufferedReader reader = null; private StringTokenizer tokenizer = null; public FastScanner(InputStream source) { reader = new BufferedReader( new InputStreamReader(source)); } public String next() { if (tokenizer == null || !tokenizer.hasMoreTokens()) { try { tokenizer = new StringTokenizer(reader.readLine()); } catch (IOException e) { throw new RuntimeException(e); } } return tokenizer.nextToken(); } public int nextInt() { n = 0; minus = 0; String str = next(); if (str.charAt(0) == '-' ) { minus = 1; } for ( int i = minus; i < str.length(); i++) { n *= 10; n += ( int )(str.charAt(i) - '0' ); } if (minus == 1) { n *= -1; } return n; } public long nextLong() { m = 0; minus = 0; String str = next(); if (str.charAt(0) == '-' ) { minus = 1; } for ( int i = minus; i < str.length(); i++) { m *= 10; m += ( int )(str.charAt(i) - '0' ); } if (minus == 1) { m *= -1; } return m; } } |
ステータス
項目 | データ |
---|---|
問題 | 0971 - 島の創造 |
ユーザー名 | ei1710 |
投稿日時 | 2019-05-20 15:22:16 |
言語 | Java |
状態 | Accepted |
得点 | 10 |
ソースコード長 | 5933 Byte |
最大実行時間 | 430 ms |
最大メモリ使用量 | 46300 KB |
セット
セット | 得点 | Cases | |
---|---|---|---|
1 | Easy | 1 / 1 | *easy, *sample* |
2 | ALL | 9 / 9 | * |
テストケース
ファイル名 | 状態 | 実行時間 | メモリ使用量 | # | |
---|---|---|---|---|---|
input-sample1 | AC | 104 ms | 23012 KB |
1
|
2
|
input-sample2 | AC | 98 ms | 24836 KB |
1
|
2
|
input01-easy | AC | 111 ms | 23156 KB |
1
|
2
|
input02-easy | AC | 118 ms | 23088 KB |
1
|
2
|
input03-easy | AC | 106 ms | 23348 KB |
1
|
2
|
input04 | AC | 367 ms | 28272 KB |
2
|
|
input05 | AC | 299 ms | 28460 KB |
2
|
|
input06 | AC | 338 ms | 29860 KB |
2
|
|
input07 | AC | 360 ms | 29876 KB |
2
|
|
input08 | AC | 372 ms | 36948 KB |
2
|
|
input09 | AC | 390 ms | 38384 KB |
2
|
|
input10 | AC | 387 ms | 39140 KB |
2
|
|
input11 | AC | 430 ms | 46152 KB |
2
|
|
input12 | AC | 367 ms | 46300 KB |
2
|
|
input13 | AC | 95 ms | 34980 KB |
2
|
|
input14 | AC | 99 ms | 37164 KB |
2
|