😊

AtCoder Beginner Contest ABC429 解法メモ

に公開

文中で使用しているのは、たとえCodonが使えようとも、同じくPythonライクでAtCoderに最適な言語の1つNimです

ABC429

ABC429A - Too Many Requests

解法

1..Nのiで、
echo if i<=M: "OK" else: "Too Many Requests"とすればよい
ACコード

ABC429B - N - 1

解法

Aの合計からどれか1項引いたものがMになるかどうかを判定すればよく、
echo if (0..<N).toSeq.anyIt(A.sum-A[it]==M): "Yes" else: "No"とすればよい
ACコード

メモ

Aの合計からMを引いたものがAにあるかを判定してもよい
ACコード

ABC429C - Odd One Subsequence

解法

A.toCountTableとして、ある種類の数字kとその出現個数vの組を求めておく
答えは、
ある種類から2個取り出す場合の数_vC_2=v*(v-1) div 2と、
残りの1つを選ぶ場合の数N-vをかけたものを、
全種類にわたって足し合わせたものになる
すなわち、
for k,v in A.toCountTable: a+=v*(v-1) div 2*(N-v)となる
ACコード

メモ

残りの1つの場合の数を、種類数-1と早とちりしてWA

ABC429D - On AtCoder Conference

解法

Mが大きいので、iに沿って計算するとTLEになる
ある位置をスタートし、出会った人数がC以上になって止まるまでに出会った人数Xについて考えると、
どこに何人立っているかを整理してしまうことで、
人のかたまりの間のどこからスタートしたところで、初めに人と出会う地点まで等しくなることに気付く
さらに、実際には、高橋君は0+0.5~M-1+0.5からスタートするが、この0.5をずらしても本質的な意味が変わらないことにも気付けば、
AのCountTableをとってkeysでソートし、
CountTableの要素数nにわたって、前のkeysとの間隔に、そのときのXをかけていって足し合わせればよいとわかる
実際には周回するが、各keysにMを足したものを追加しておけば、C\leqq Nゆえ十分である
X尺取り法で、1..nのlに対し、間にいる人数合計がC以上になるまでrをずらしていけばよく、
lが進むときに、そこにいる人数を減らしていけばよい
l-1lとの距離差をかけながら、足し合わせれば答えとなる
ACコード

メモ

CountTableすべきことはすぐにわかったが、入力例2のヒントがあるにもかかわらずiに沿った実装を始めてしまい、時間を溶かした
keys単位で算出することにも気付くが、0.5をずらしても本質に変わりがないことに気付かず、実装できなかった
もちろん、Aの長さを倍にせず、mod n等を使って処理することもできる
ACコード

ABC429E - Hit and Away

解法

すべての安全な頂点からの多始点BFSを考えれば、危険な頂点に最短、次点で到達した2つの時間を合計して答えればよいとわかる
ただし、相異なる安全な頂点からの到達でなくてはならないので、実装においては、
Dequeに(現在の頂点番号,出発した頂点番号,経過時間)のタプルを持たせ、
頂点到達記録用のdは各頂点ごとに配列で用意し、(出発頂点番号,到着時刻)のタプルを加えていく
訪問を許すのは、その頂点のdの要素が2つ未満で、すでに到着していても同じ出発頂点でない場合とすればよい
答えは、BFS終了後、Sを順にみて、'D'のときに、d2つの到達時刻の和を出力していけばよい
ACコード

メモ

危険な頂点からBFSし、安全な頂点に2つ達したら打ち止めと考えたがTLE
多始点BFSも考えたが、やはり危険な頂点を始点としたため、実装できなかった


反復学習にはmochiがおすすめ
全問入ったdeckはこちら

Discussion