/ 最近 .rdf 追記 編集 設定 本棚

log[20200607] 第一回 アルゴリズム実技検定 過去問/K 問題 巨大企業 | 第三回 アルゴリズム実技検定 過去問



20200607() PAST とエロゲは同じ値段AtCoder 緑色は初級と中級に分かれるらしいが()第一回なら中級の目があった>自分の提出わざわざ初級認定をもらいたくはないが中級なら無料だった第三回は昨日終わっている第一報があったときに確認したサンプル問題は明らかに難しくて「取るべき問題をすべて取ってさらに23問のまぐれ当たりを上乗せしてやっと中級という感触だったんだそれで見逃した

最終更: 2020-06-09T19:05+0900

[AtCoder] 第一回 アルゴリズム実技検定 過去問K 問題 巨大企業

答えを出すだけなら簡単社長を頂点とするピラミドを遡るあいだに上司として出くわすかどうか確認するだこういう問題は好き逆にいつまでも数が合わない数え上げ問題は嫌い>禁止された数字への自分の提出そもそもサンプルへの答えがいつまでも一致しないから提出に至らないスクリトが山ほど隠れている

簡単ならどこが問題

 最初の提出 #14088806 (RETLE)

N の上限が15万だからそして組織が非効率の極み直列15万階層だったなら1つのクエリに答えるために15万マイナス1回階層を上らなければいけないクエリは最大10万個ある

そこは一応読めていたので社員ごとに社長から何階層下にいるかという情報をメモしておいて社員間の階層の隔たりと同じ回数だけ上司をたどれば答えが出せるようにしていたでも TLERE最悪の場合はやっぱり15万マイナス1回たどらなければいけないのだからTLE はまあ当然

 2番目の提出 #14089327 (RE)

社長から始めて決まったやり方で社員を一列に並べていったらある社員とその部下と部下の部下以下末端までを一定の連続する範囲で表せるのではないかと考えたなんのことはないそれって深さ優先探索と同じ順番だったのだけど

それで TLE はすべてなくなった1度だけ15万マイナス1階層をたどってしまえばあとはすべてのクエリに定数時間で答えられる

しかし TLE はどれも RE に変わっていた最初の提出からかなりの数存在しているこの RE は何だ? RE ってだいたいはヌルポだからよくある配列の範囲外アクセスが原因だろうと考えるのを後回しにしていたしかし目を皿のようにして調べてもその可能性はなかった

 3番目の提出 #14090337 (AC / 394 ms / 22832 KB)

再帰呼び出しをやめてスタック変数を……というと意味が違うスタック構造を持つ変数をスタックの代わりに使うようにしたら通ったので呼び出し階層が深すぎたのが RE の原因だった最悪で15万マイナス1階層は深すぎるだろうなあ(最初から読んでおけ)

 4番目の提出 #14102282 (AC / 394 ms / 21500 KB)

  • N 回繰り返す前処理のループで if を取り除いた
  • if を取り除いたことでスタックを社長で初期化するときに検索がいらなくなった一石二鳥
  • 変数 T,L,R は一列に並べた組織構造(T)そこに張った社員ごとのインデックス(L,R)という役割だったのだけど実は T は配列である必要がなくカウンタ変数で十分だった(RDB でもインデックスに情報がすべて載っていて表がいらないケースがあるよ)

しかし実行時間は変わらRuby によるすべての提出(実行時間昇)を参考にすると

  • 回答の出力を一行ずつではなくまとめた方が速い(シスムコールを減らすの類だと思)
  • スタック(変数)に一度に要素を詰め込まない方がたぶん速い
  • p メソドが puts メソドより遅いかもしれない

ということが言えると思う他に差がつく要素があるだろう

最終更: 2020-06-26T13:37+0900

[AtCoder] 第三回 アルゴリズム実技検定 過去問

 自分のすべての提出

やはり解けたのは K 問題までだったただし第一回と違って途中で1問落としたりはしていないもうひと踏ん張りで80点を超えて上級だけど残された問題の予想される難しさと裏腹に考える時間が残ってないんだよなあ(本番じゃないので途中でお風呂に入って本を読んだりしていたけども)

第一回第三回に共通する問題の傾向として数学的応用的な要素が抑えられていて愚直に効率的なコドが書ければ解けるものが選ばれている印象よく知らないけど一般的なお仕事コングに寄せていこうとしてるのかな基礎的な知識とその初歩的な運用に漏れ抜けがないことを確認しようとしてるのかな(緑色以下のコーダーには保証できることがないというツイトを見かけたのでこのへんとか>https://mobile.twitter.com/chokudai/status/1274756588624965632)

 L 問題 スーパーマーケ

Python で解けることは運営元で確認してるらしいので()Ruby でも方法はあるはずなんだよなあ

タイムだけちらっと見た>Ruby でのすべての提出提出数は4つでユニークユーザーは2人2689 ms < 2726 ms < 2747 ms < 3735 msっぱり方法はある

TLE のケースはメモリの食い方が特異的に大きいっと 1.5他のケースを見ると必ずしもタイムとメモリ消費量のあいだに比例関係があるわけではないメモリの割に時間がかかるのは M が大きいんだろうTLEースは M も大きいんだろうけど特に NK が大きそうK が大きくても配列の shift はポインタのインクリメトで済むようなので(Ruby-1.9array.c で確認)あまり影響がないdelete_at(1)[1]=[0] and shift に置き換えたら一部速くなったからっぱり shift は問題ない(提出 #14129916提出 #14130610)N が大きいと……M 回のループで4回ずつ行う二分探索の時間に影響するN は棚の数だから商品数(メモリ)と商品の検索(時間)の両方に響く問題手前から ai 番目までにある商品を見た後見た商品のうち最も消費期限の値が大きいものを選んで棚から取って購入しますだから棚を選ぶ検索は避けられない方法があるとしたら予めうまいことソトしてしまってループの中では検索しないか4回を2回に減らすか……

 M 問題 行商計画問題

 提出 #14141040 (Ruby / TLE)

半分以上がTLEAC17個あるからやり方は間違ってないと思うしかし PAST の問題が考察よりも実装重視の傾向を持っている以上TLEに甘んじるわけにはいかないでも無理ぽ

 提出 #14144878 (C++ / WA)

TLE がすべて WAAC になりましたC++ のちからTLE の陰に WA が隠れていたということでやり方が間違っていた

 提出 #14145227 (C++ / AC / 1695 ms / 74616 KB)

Visited フラグを立てるタイミングを誤っていたのと訪れなければいけない街と街のあいだの移動コトを計算するときに訪れなければいけない別の街を通ってしまう場合の考慮が抜けていた

この問題を Ruby試験時間内に解けるなんてことがある? ちなみに現在 RubyAC 提出はない>Ruby によるすべての提出

ところで1695 msC++ 最遅だったC++ を使うなら2桁msで解けるらしい

 問題名で検索した

訪れなければいけない街と街のあいだの移動コトを計算するときに訪れなければいけない別の街を通ってしまう場合の考慮が抜けていたと書いたその対策として関心のない街を迂回するルトを2街間の最短経路として採用するようにした(たぶんルトなしにした方が良かった)もし他の街を中継するルトの方が結果的に低コトならそのルトは2本以上の2街間最短ルトの組み合わせとして現れてくるので

でもこのステップで求めるものを2街間の移動コトに加えてその際に通過する街と定義したならっと速くゴールにたどり着けていたかもしれない

解答は2パトに分かれているがどうやら後半は幅優先探索ではなく DP でやるものらしいもちろんその方が最遅より速くなるだろう

でもまだ……一度通過した街に戻るのにも移動コトがかかるから状態や遷移には現在位置が関わってくるそれをベトコンベヤ式に取り扱って答えにたどり着けるイメージが湧かない二次元の遷移が解らない

 色と認定の関係

https://mobile.twitter.com/atcoder/status/1273915562989502465

 現在 M 問題で唯一 AC を獲得している Ruby による提出 #14152776

気がついたこと

  • (たぶんルトなしにした方が良かった)もし他の街を中継するルトの方が結果的に低コトならそのルトは2本以上の2街間最短ルトの組み合わせとして現れてくるのでと書いたがあれは嘘だった
  • 注目している K 地点間の移動コトは K*(K-1)/2 通りを調べるのではなくK 通りを調べるのが良さそう

    終点を K 地点に限って試行回数を増やすより終点を N 地点から限らず試行回数を K 回に留めるということ

  • 後半はワーシャル-フロド法に見える3重ループ

    ただし街と街を結ぶ中継地点(一番外側のループ)は街ではなく経由地のリ