【競プロ典型90問】012の解説(python)
概要
競プロ典型90問の解説記事です。
解説の画像を見ても分からない(理解力が足りない)ことが多々あったので、後で解き直した際に確認できるようまとめました。
問題012-Score Sum Queries
問題概要
白で塗られたH×Wのマス目に対して、以下の2パターンのいずれかのQ個のクエリを処理する。
1. 白いマス(r, c)を赤で塗る
2. (r1, c1), (r2, c2)の2点が与えられた時、以下の条件をどちらも満たしているか判定する
- 2点が共に赤く塗られている
- 2点が赤いマスを辿っていけば、連結している
解き方
この問題は、Union-Findを知っているか知らないかの問題です。
一応、簡単に説明すると、Union-Findとは、グループ分けの管理を非常に高速に実装できるデータ構造で、
ある集合のグループ分けや、同じグループに属しているかなどを高速に判定することができます。
Union-Findについての詳細は、ぜひ以下のスライドなどをご参照ください。
引用元:Union find(素集合データ構造) from Atcoder Inc.
Union-Findを用いると、各クエリの処理は以下のように、考えられます。
1. 白いマス(r, c)を赤で塗る
→ 白いマスを赤で塗り、隣接しているマスに赤いマスがあれば、連結させる。
2. (r1, c1), (r2, c2)の2点が与えられた時、赤いマスを辿っていけば、2点が連結している
→ 同じグループに属しているかを判定する
ここまで、手順が分かったので、以下で実際に実装していきたいと思います。
引用元:競プロ典型90問 Github
実装
# 入力の受け取り
H, W = map(int, input().split())
Q = int(input())
# 二次元配列を一次元化する関数
def flatten(h, w):
return h+(H+1)*w
# 赤塗りかどうかを判定する配列。配列の要素数をnに格納。
M = [False]*((H+1)*W)
n = len(M)
# UnionFindの実装例
class UnionFind():
def __init__(self, n):
self.n = n
self.parents = [-1] * n
def find(self, x):
if self.parents[x] < 0:
return x
else:
self.parents[x] = self.find(self.parents[x])
return self.parents[x]
def union(self, x, y):
x = self.find(x)
y = self.find(y)
if x == y:
return
if self.parents[x] > self.parents[y]:
x, y = y, x
self.parents[x] += self.parents[y]
self.parents[y] = x
def same(self, x, y):
return self.find(x) == self.find(y)
# 要素数nを入れて、Union Findのインスタンスを作成。
uf = UnionFind(n)
for _ in range(Q):
q = list(map(int, input().split()))
# ti = 1の時、[r, c]を赤く塗り、隣接マスを探索、もし赤なら、グループを結合する。
if q[0] == 1:
r, c = q[1]-1, q[2]-1
x = flatten(r, c)
M[x] = True
for i, j in [[0, 1], [0, -1], [1, 0], [-1, 0]]:
r_dash, c_dash = r+i, c+j
y = flatten(r_dash, c_dash)
if 0 <= r_dash < H and 0 <= c_dash < W:
if M[y]:
uf.union(x, y)
# ti = 2の時、[r1, c1], [r2, c2]が共に赤なら、同じグループに属するか判定。
else:
x = flatten(q[1]-1, q[2]-1)
y = flatten(q[3]-1, q[4]-1)
if M[x] and M[y] and uf.same(x, y):
print("Yes")
else:
print("No")
最後に
問題の解説を読んでも他の人のコードを見てもさっぱり分からないという方の
力に少しでもなれれば幸いです。
コードの改善点やその他、ご意見、ご質問などあれば、気軽にコメントください。
ここまでお読みいただきありがとうございました。
Author And Source
この問題について(【競プロ典型90問】012の解説(python)), 我々は、より多くの情報をここで見つけました https://qiita.com/wihan23/items/14202eafc6e0840630d7著者帰属:元の著者の情報は、元のURLに含まれています。著作権は原作者に属する。
Content is automatically searched and collected through network algorithms . If there is a violation . Please contact us . We will adjust (correct author information ,or delete content ) as soon as possible .