AtCoder Beginner Contest 177 振り返り
D - Friends
・友達の友達は友達
・友達同士がいないように分ける場合,最低何グループ必要か
解)
最大の友達集合の大きさを求めればよい.
Union Find 木構造が役に立つ.
実装:
parent[] は大きさN,-1を初期値とし,parent[i]には i の根を格納.
iが根の場合はグループの要素の数を負で格納.
根を見つけ,道中にある数字の根も書き換える関数.
負の数(グループの構成要素数)
根をつなぎなおす関数
例:
入力を
7 5
1 7
2 6
3 5
4 5
4 6
とすると,
#i について
f:0
[-1, -1, -1, -1, -1, -1, -1]
i:0
#j について
f:6
[-1, -1, -1, -1, -1, -1, -1]
j:6
#unite内のparent書き換え
[6, -1, -1, -1, -1, -1, -2]
f:1
[6, -1, -1, -1, -1, -1, -2]
i:1
f:5
[6, -1, -1, -1, -1, -1, -2]
j:5
[6, 5, -1, -1, -1, -2, -2]
f:2
[6, 5, -1, -1, -1, -2, -2]
i:2
f:4
[6, 5, -1, -1, -1, -2, -2]
j:4
[6, 5, 4, -1, -2, -2, -2]
f:3
[6, 5, 4, -1, -2, -2, -2]
i:3
f:4
[6, 5, 4, -1, -2, -2, -2]
j:4
[6, 5, 4, 4, -3, -2, -2]
f:3
[6, 5, 4, 4, -3, -2, -2]
f:4
[6, 5, 4, 4, -3, -2, -2]
i:4
f:5
[6, 5, 4, 4, -3, -2, -2]
j:5
[6, 5, 4, 4, 5, -5, -2]
# 答え
5
(参考)
Submission #16326133 - AtCoder Beginner Contest 177
E - Coprime
集合{Ai}から任意の2つの要素を選んでも互いに素であれば pairwise coprime
上記を満たさないが全要素の最大公約数が1であれば setwise coprime
上二つの条件を満たすかどうかを判定する.
(制約)Ai の長さNは10**6以下,要素の大きさも10**6以下.
解)高速で素因数分解をし,要素に重複があるか調べればよい.
前計算で2と奇数から約数候補を生成する.
main関数では,最初に各数字を入れた配列を作成する.
ここで先ほど作成した約数候補を用いて,約数の重複がなければpairwise coprime
setwise coprime はgcd関数を利用すればよい.
3つ以上の数の最大公約数を求めるには複数回使用する必要があるが,reduce関数を利用することで簡潔に書ける.
(参考)
Submission #16392807 - AtCoder Beginner Contest 177
F - I hate Shortest Path Problem
右あるいは下に動くことができる.
K+1番目までの最短ルートを求めたい.
解)
縦方向の移動量は等しいので,横方向の移動の最小量を求めればよい.
初期位置と現在位置のずれが最小であるものを求めたい.
各行における答え ret,
初期位置と現在位置を保管しておくdp0とdp,
直進できる場合のインデックスと直進できない場合の最小値のインデックスをarg0,argとして更新していく.
このままでも計算できるが,TLEするものが一つある.
1000行おきに一回流れをまとめて初期位置,現在位置などを残っている流れに応じて初期化することで計算時間を短くすることができる.
(参考)