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

脳log[20210721] 第七回 アルゴリズム実技検定 過去問



2021年07月21日 (水)

最終更新: 2022-02-17T12:53+0900

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

第四回までの日記>20201111p01

課金ユーザーじゃなくてごめんね。@atgolfer1 に流れてきたツイートを見てはじめて問題が公開されていること、第七回が行われていたこと、終了していたことを知ったよ。

 A - チェックディジット

やるだけ。提出 #24382962

 B - 蒸気圧

小さい方を選ぶだけなんだけど、10 分以上切り捨てたり余りを取ったりして悩んでいたのは内緒。提出 #24383193

 C - 入力チェック

Ruby なので 10 進 100 桁はなんの障害でもなかった。提出 #24383281

 D - 書き換え

5つのパターンをじっと見れば最終結果に影響するような文字の取り合いがないことがわかる。提出 #24383341

 E - 青木君のいたずら

探索が許されていることと操作が1回に限られていること、それと遷移が足し算ではなく掛け算だという点が違うけど、問題の形としては ARC122 の C 問題 Calculator を思い出した>20210612p01.03。これが解ければ ARC122-C も解ける!

提出 #24383572

 F - ダブルブッキング

スケジューリングの問題だけど、求められているのが最適化ではなく判定だという点で、最も簡単な部類。提出 #24383711

 G - べき表現

20 分考えた。

どんな正の整数でも、テキトーに選んだ正の整数を基数としてその冪乗の和で表せるのは当然だけど(N 進数ってそういうもの)、使える数字が 0 と 1 と -1 に限定された 3 進数ではどのように事情が異なってくるか、という問題。

2×3^x = 1×3^{x+1} - 1×3^x

という感じで、2 を -1 に置き換えてから次の桁にツケをまわしていくのがいいでしょう。提出 #24384055

 H - 折れ線グラフ

解けてないよ。制約が小さいから探索していいのだろうけど、それでも 100 の 100 乗になるようなバカな探索は許されない。私はバカです。

 @2021-11-15 TLE→AC

上限の揃った制約が DP だと告げている。それも3乗の。まだ8問目だからって雑な探索で解けるとなめてかかっていたのではないか?

  1. 提出 #27281059 (TLE×4) 腰を据えてもこれである
  2. 提出 #27281255 (AC / 476 ms)

なだらかな折れ線グラフを書きたいのだから、遷移先の幅は自ずと限られる。(W = A.sum/[N-2,1].max+1 -2, +1 はテキトー)

 I - ほくろ

ABC-D 虐殺三銃士」のひとつ「Congruence Points」を思わせる問題だけど、両目の位置を手がかりに確定した情報が得られるところが優しい。

図形問題は行列や複素数に計算を丸投げしがちなので、これは自分で式を書いた。25 分かかった。提出 #24392172

 J - 終わりなき旅

強連結成分分解をしよう」がキーワードだった競プロ典型 90 問の 021 - Come Back in One Piece(★5)がすぐに思い浮かんだんだけど、深さ優先探索を2回するんだというアルゴリズム解説は何か所かで読んでたんだけど、これは 17 問ある★5問題のうちで解いてない3問の1つなのだった。

雰囲気は掴んでいたので雰囲気で書いた。提出 #24393748。細部が詰められてなくて無駄があるかも。競プロ典型 90 問のおかげでアルゴリズムの顔見せだけは済んでいたので、今度は実装するところまでこぎつけた。

 K - 急ぎ旅

理解が甘くて 1 TLE。実装ミス(< にすべきところを <= にしていた)で 1 WA。AC はこれ>提出 #24424698

最短経路問題ならダイクストラ法なんだけど、満足度と所要時間の2つを考えなければいけないのをどう考えるか。所要時間が最短であることが第一で、満足度の高さはその次に考慮すればいいだけなんだけど、だけど、「満足度について、同じ都市を 2 回以上経由してもその都市の景観は 1 回しかカウントしません」という文言がちょっとひっかかるよね。経路を記録して重複を排除しないといけないの?(それには無視できないコストが……)

もちろん負の移動時間はないから、同じ都市を2度訪れる経路が最短になることはない。だけど次の2つのようなパスで所要時間の合計が同じになる場合をどのように扱うか迷った。

都市 M に着いたときの満足度の総和は明らかに2、3、4を経由してきた経路の方が大きくなるんだけど、もう一方の経路は M のあとで7、8、9を経由することで取り返すことができるかもしれない。M に着いたときの満足度の低さを理由にして一方のパスを捨てていいのかどうか。

実は上の図には嘘があって、上の図のような状況の実際は下のようになっている。

これは1と M とのあいだの最短所要時間と、M と N とのあいだの最短所要時間がどちらも1つの値に決まることからわかる。最短経路であるどの2つのパスを取り上げても、分岐と合流を繰り返す第3のグラフのような関係になることが納得できたら、ある都市に最短で到着する経路のなかから最大の満足度を記録するのでいい。

 L - たくさんの最小値

セグメントツリーなんだけど、最小値を持っているインデックスをどうやって列挙するかという問題。

最小値の記録と添字の記録をセグメント木と配列で分担しようとして TLE を出したり(提出 #24408482)、セグメント木の実装ミスで大量の WA を出したりしつつ(提出 #24412768)、三度目の正直で AC>提出 #24413254

セグメント木を上から下に下るのって苦手。(根っこが上です。逆にすると頭が働かない)

 M - 分割

全部を分割した状態から始めて、損をしない範囲で統合していくのかなと思ったけど、並べ替えができなくて境界が入り乱れるのを、どう整理して扱えるのかわからない。

とある赤亀コーダーさんによると全体でこの M が一番難しかったらしい。

 N - モノクロデザイン

昨日これの簡単なバージョンを解いたよ>「B - すぬけ君の塗り絵 2 イージー」(提出 #24414821)。

二次元累積和かなと思うんだけど、ABC203-D Pond競プロ典型 90 問の 081 Friendly Group(★5)もまだ解いていない。二次元累積和って累積和の累積和とは違うんだなー、という感想を持ったのは覚えてるけど、よく思い出せない。

 O - コンピュータ

O 問題が解けたのは初めて。

入力を圧縮したり累積を記録したりして計算量を削減するのは、競プロ典型 90 問の 089 - Partitions and Inversions(★7)ぽいなーと思った。

以下は考えたこと。

  1. ある B より後ろにあって、前にある B と同じかそれより小さい B は無視できる。
  2. だから N 個の入力は、B の増加列といくつかの A を足してまとめたもののペアとして圧縮できる。
  3. 最終日までに得られる報酬の総額は決まっている。コンピュータに支払う金額をどれだけ減らせるかという問題。
  4. 十分な資金があるなら明らかに B の最大値と同じ値段のコンピュータ1つだけを買うのが最適。
  5. しかし資金が足りない場合は目の前の障害(B)を超えられるだけのコンピュータを買って、目先の報酬を得るようにしなければいけない。
  6. なんですかね、貧しさ故に最適な選択ができないって、現実ですか。保険とか追証とか宝くじとか。
  7. 複数の買い方。障害(B)が1、2、5、6、9と並んでいるときに、1を買って5を買って9を買うのがいいか、2を買って6を買って9を買うのがいいか。局所的な判断では決まらないので貪欲法は使えない。
  8. 迷うたびにキューを伸ばすと爆発するので DP っぽいなー。
  9. N^2 のループは許されていないので、すべての i についてそれより後ろにあるすべての要素を処理対象にすることはできない。
  10. i<j<k とする。コンピュータはできるだけ買わないのが正解だから、ある i と j がともに k にある障害を越えるというとき、j から k への遷移が i から k への遷移より得するということはない。
  11. i を通過する時点ですでに k を超えられるだけのコンピュータを買う資金があるのだから、到達地点が同じ k なら j で足踏みする価値がない。
  12. j で足踏みする価値は k より遠くへ(k を超えて一足飛びに)到達できる可能性にある。
  13. という感じであとはがんばってコーディングする。提出 #24429839
  14. .each_with_index.each とか謎なことしてる……。幸いにしてこれは無駄なだけで害はないけど、部分的な修正を繰り返すとこういう風に、(通して書き下したときにはありえない)謎なバグを仕込みがち。