AtCoder Beginner Contest 197(Sponsored by Panasonic)参加記(~E問題)
D問題みたいな数学問題もっと出してもいいんですよ
B - Visibility
むずくない?
マスから始めて、上下左右の4方向に向かって探索する。もし探索途中に#
が出現したら、それより奥のマスは障害物で遮られて見えないので探索をやめる。この個数をカウントしたものが答え。
計算量は、入力がボトルネックで。探索自体はである。
C - ORXOR
「長さの数列を1つ以上の空でない連続した区間に分ける」、つまり、各要素の間に区切りを入れるか・入れないかを独立に選択する方法は全部で通り。制約よりは最大でもなので、全パターンを試しても間に合う。こういう、「選ぶか」「選ばないか」の2択をいくつか選択するような状況の全探索にはbitを活用する。(bit全探索という)
C++では、ORの計算はa|b
、XORの計算はa^b
と書くことで簡単に計算できる。
計算量は、。
D - Opposite
正多角形の座標のうち、一番離れている2点の座標が与えられる。は偶数なので、この正多角形の中心の座標がわかる。
また、正多角形の隣り合う頂点は、正多角形の中心から見てちょうどだけ回転している。2次元平面状の座標を回転させるには、回転行列を用いるとよい。具体的には、
を用いればよい。ググると出てくる。
答えが小数になるため、誤差に注意。
計算量は、。
E - Traveler
色のボールを回収するとき、現在の座標をとすると、
・負の方向に進んでから正の方向に進む
・正の方向に進んでから負の方向に進む
という2通りの行動以外は最適な行動ではない。(引き返した分の時間が損であり、引き返さなくてもすべてのボールを回収できる行動が存在するため。)
つまり各色のボール群を回収する際は上記の2通りの行動のうちどちらかを選んで行動する。この時点で全通りを試すとの計算量となり、実行時間制限に間に合わない。
ここで、ある色までのボールを回収し終えた時点での座標は、その色のボール群のうち一番座標が小さいボールがあった位置か一番座標が大きいボールがあった位置かのどちらかである。それまでの行動を考慮しなくても、前の段階での終了時の座標を全通り試すだけで最適解が求まる。これを、動的計画法(DP)という。
よって、ひとつ前の色の座標の候補(2通り)と、ボールを回収するときの行動パターン(2通り)の全パターンを試して最適なものを選択していけばよい。
計算量は、。
感想
EのDPは比較的簡単な方の部類だと思うのだが、コンテスト中は嘘の貪欲を書いていた。強くなりたい…!
AtCoder Beginner Contest 196参加記(~E問題)
水色なのにCでWA出たのでだめです
A - Difference Max
を大きくするとの値も大きくなる。逆に、を大きくするとの値は小さくなる。なので、の値を最大化する場合、は最大に、は最小にすればよい。つまりが答え。
最大化するときの基礎的な考えが問われる良問。
計算量は、。
B - Round Down
C++を使ってる前提で話すと、なんてデカい数は扱えない。文字列で受け取れば、「小数点以下を切り捨て」したいので、文字列の先頭からピリオドが登場する手前までを切り取って出力すればよいことがわかる。先頭から1文字ずつピリオドかどうか判定しながらちまちま出力すればよい。
計算量は、。
C - Doubled
解けなかった。
制約がある程度大きいのでで解こうと思ったがどこかで実装をバグらせたらしくWAが出た。想定解は前半の桁だけ全探索して以下か判定するというもの。発想としては全く難しくない。過去に類題も出てるのになぜその発想に至らなかったのか…。
計算量は、。
D - Hanjo
制約が小さいので、ピースの置き方を全探索する。再帰関数によるDSFを書いた。残りの畳の枚数と現在の敷き詰め状態を引数として渡す。もし空白のマスが存在していたら、そこに「縦長」「横長」「正方形」の3種類を敷き詰めた状態をそれぞれ作って再帰呼び出しする。もう置けない状態なら1を返す。こう書くと、返ってきた値の総和が求める通り数になる。状態数は超ざっくり見積もって最悪でも通りしかない(実際にはさらに少ない)ので全探索しても実行時間制限に十分間に合う。
E - Filters
考察を書く。間違っている可能性が大いにある。
もしくはが登場するまでにに足された数の合計をとすると、である。クエリが来る前段階では定数なのでこの答えはすぐに求められる。さらにと書ける。さらにさらに、関数の定義から、のほうが選ばれなければそれ以降が解に干渉してくることはない、つまり前から見て番目の関数でのほうが採択されなかったときの答えは事前に計算しておくことが可能である(計算量の話はあとで考える)。なので、とのどちらかがある定数より小さいことが判明すれば、その時点で解が定まる。関数が個あったとすれば、数直線が個の区間に分割され、さらにクエリで与えられる数値はその区間のどこかに必ず含まれる。
つまりどういうことかというと、「クエリで与えられた」と「関数のしきい値」をソートして前から見ていけばで答えが求まるのではないか?ということだ。
この「数直線を個の区間に分割する」ことで先ほどの前計算(が絡まない場合)の解も求められそう。(ここが求められずに時間が来てしまった)
ここで脳みそが疲れたのでやめた。
公式解説によると、この定義の関数は合成することができるらしく、「定数(低)」「」「定数(高)」の3パターンしかないとのこと。クエリの数がバカ多いので合成できそうだとは思ったが合成した後のグラフの形がなぜエスカレーターみたいになるのかはわからなかった。
感想
コンテスト終了後もE問題を粘って解いていたが頭が腐っていたので解けなかった。レートが20くらい無くなった
AtCoder Regular Contest 114参加記(~B問題)
早解きの巻
A - Not coprime
互いに素でないということは、とに共通の素因数が存在するということと同値である。制約より、は最大でも以下の素数の積(およそ)にしかならない。さらに、以下の素数それぞれに対して「に含めるか」「含めないか」の2択を選ぶbit全探索をして全通り試してもも実行時間制限にも十分間に合う。
ちなみに以下の素数は個。素数リストを実行時に生成してもよかったが、ライブラリを引っ張り出してくるより暗記しているものを書き出したほうが早かった。
計算量は、。
B - Special Subsets
全射の整数集合が与えられていて、その部分集合のうち全単射であるものはいくつあるか?という問題。(たぶん)
この集合と関数の関係は、へと有向辺を生やしたグラフと等価である。このグラフは、頂点数と辺数がそれぞれで等しい。
また、関数が全単射であるとき、有向グラフはいくつかの重複しない閉路のみからなるグラフとなる(必ずしも連結とは限らない)。
つまり元のグラフのなかに閉路がいくつ存在するかがわかればよい。これは単純にDFSで閉路判定をすればよいし、「頂点数と辺数が等しいグラフの閉路の数は、連結成分の数に等しい」という定理をもちいてUnionFindなどを用いて連結成分の数を持つだけでも良い。
閉路の数をとすれば、答えはである。
計算量は、。
感想
Cは解けなかった。サンプルが合わなかった。
D問題をみて「貪欲かな~」と思ったけど、順位表を見るとD-EのAC数が逆転していたのでC問題をずっとにらんでいた。貪欲は嘘解法らしく一安心。
個人的に早解きで暖まるのは申し訳ない気持ちになる。
AtCoder Beginner Contest 194参加記(~F問題)
Fがむずすぎる
青パフォ
B - Job Assignment
問題文を読んだ時点で、計算量がでも解けることを確信したので制約を見ていなかった。実はでも通るらしい。こういうところで実装をサボらないとなんだか損した気分になる。
コンテスト中は場合分けしてで解いた。
1. 仕事 A と仕事 B をそれぞれ別の従業員に割り当てる場合
の最小値を、の最小値をとする。
分で仕事ができる従業員と、分で仕事ができる従業員がそれぞれ別になるように割り当てられるか調べる。具体的には、
・となるようなが2個以上ある場合
・となるようなが2個以上ある場合
・となるようなが1個のみ かつ となるようなが1個のみ かつ
のどれかの場合、答えはとなる。上記に当てはまらない場合、を満たす従業員が仕事Aか仕事Bを行うのは確定しているので、従業員を除いた人の中で一番早く仕事Aもしくは仕事Bをこなすことができる従業員をkを探す。よって答えはとなる。
2. 仕事 A と仕事 B をどちらも同じ従業員に割り当てる場合
答えはの最小値である。
これらの答えの最小値が最終的な答えである。
計算量で解くなら、従業員のペアを全探索してシミュレーションし、その最小値を求めればよい。
C - Squared Error
式が正しいかどうか自信が無いがとりあえず書いておく(間違ってたらごめんなさい)。
式変形すると、
となる。
ここで、
であり、
である。これは累積和を用いることでで求められる。(参考:過去問に下位互換となる問題が出題済み。C - Sum of product of pairs)
よって全体でも計算量で答えを求めることができる。
D - Journey
わかってないけどAC。
まだ選ばれていない頂点が選ばれると、「すでに選ばれた頂点の集合(連結)」と連結になる。つまり、最初に高橋君がいる頂点1以外の頂点をすべて選ぶまでの回数の期待値は?という問題になる。これはたしかガチャコンプ問題とかいう名前(俗称)がついていて、結構頻繁に出題されている(のに、未だに理解できていない)。
期待値の求め方がわからないので「期待値 回数 計算」でググると高校数学の美しい物語さんがヒットする。
mathtrain.jp
ここにそのまま答えが書いてある。どうやら期待値は漸化式を使って表現できるらしい。種類すでに引いている場合の期待値を考えると上手くいく?
とりあえず漸化式が立てばそれを更新していくだけなので、計算量はである。
期待値の問題が苦手ということがわかったのでどこかで特訓したい(しない)
E - Mex Min
数列のなかで、連続する個のの最小値は?という問題。
関数の定義より、個ある整数の中に、とある整数が含まれていなければ、関数の返す値は少なくとも以下となることがわかる。なので、からまでの整数それぞれに対して、が含まれない区間の長さの最大値が求められれば良い。これは、数列を前から舐めていって、各整数の直前の出現位置をメモしておけば解くことができる。
あとはから小さい順に、整数が含まれない区間の長さの最大値は以上かを判定してやればよい。
計算量は、。
F - Digits Paradise in Hexadecimal
桁DPっぽさがある。
dp[i桁目まで確定][N未満フラグ][Leading Zeroを抜けたかフラグ][iビット目:iをすでに含んでいるか?を保持するフラグ(16bit)] := 総数
とすると解けそうだが、計算量が(dはd進数であることを示す、本門ではd=16)程度になり、これは回程度の計算が必要になるので間に合わない。
どうやら桁DPをしなくても解けるらしい。わかりません。
感想
Bがむずすぎる
SOMPO HD プログラミングコンテスト2021(AtCoder Beginner Contest 192)参加記(~E問題)
A - Star
高橋君が最後に 1UPキノコ ご褒美をもらったあと何枚コインを集めているかわかるなら、からその枚数を引けば必要な枚数がわかる。これは剰余算を用いて計算することができる。答えはとなる。
計算量は、。
B - uNrEaDaBlE sTrInG
まず前提として、「ある文字が英大文字か?」を判定する関数と、「ある文字が英小文字か?」を判定する関数を書いてしまう(標準で用意されているなら使い方を調べる)。こうすることで考えることを減らせるし、デバッグの速度も上がる。
文字列を先頭から一文字ずつ見ていき、奇数番目の文字なら英小文字か判定して、偶数番目の文字なら英大文字か判定すると解ける。一文字でも条件を満たしていないのなら答えはNo
である。
主要な言語だと配列や文字列の添え字番号は0から始まるので、奇数・偶数が入れ替わるのがややこしいところ。
計算量は、。
C - Kaprekar Number
とりあえず、とを実装する。これは、整数を文字列に変換してからソートしてまた整数に戻す、という処理で実現可能である。これらの関数があれば、定義通りも問題なく実装できる。の計算量はである。
この関数についての漸化式が与えられている。制約を見ると求める項は最大でも番目までなので、愚直に漸化式の定義通り計算しても間に合う。
計算量は、。
D - Base n
誤読した。1桁のとき、何進数でも以下になるじゃねえか!と思って15分経ったところでclarを投げたところ、10秒でテンプレ質問が返ってきたのでいったん別の問題に逃げた。
再び戻ってよく読むと、の種類数ではなく、計算して得られる値の種類数を求める問題だった。なにこれ?あほくさ
の長さが以上のとき、の値が大きくなると得られる値も大きくなる。つまり、について条件を満たす境界を二分探索で探すことができる。の長さが大きい時、が1増えるだけで指数的に増加する場合があるのでオーバーフローに注意しながら実装すること、解が種類になるパターンもあること、の長さがのときの場合分けなど、考えることが多い。しかも問題文がわかりづらくて誤読したせいで解いた時の達成感が無かった。クソ
計算量は、。
E - Train
都市を頂点、鉄道路を辺と見たグラフを考える。このグラフの頂点から各頂点までの最短コスト(問題文中では到着までにかかる時間)を求めたいので、ダイクストラ法が適用できないか考える。
辺のコストが固定ですべて正のコストならばダイクストラ法を適用できる。もし列車が発車するタイミングちょうどに出発都市に到着した場合、コストはである。もし発車までに時間があるなら、その時間をコストに追加してやればよい。頂点への到着時刻をとすると、がコストとなる。よって、最短コストで移動している場合の辺のコストは固定であるとみなすことができ、すべて正のコストであるので、ダイクストラ法を適用することができる。
計算量は、。
F - Potion
まだちゃんと読んでない。DPっぽい。
感想
誤読も競プロのうちだけど、運営陣の発言を見てるとなんかモヤモヤするんだよなあ。どうにかならないのかな。
AtCoder Regular Contest 113参加記(~D問題)
いろいろ悔しい
A - A*B*C
最初、と誤読していた。サンプルで気付くまで15分かかった。ダメ。
は定数なので、たとえばを固定すると条件式がとなる。この式を満たす正の整数の組の個数は、以下の整数それぞれの約数の個数の総和に等しい。
よって、からまでの整数それぞれの約数の個数が高速に求められれば良い。これは計算量で求められる。これらの結果に累積和を適用することで、答えが求まる。
計算量は、。
B - A^B^C
進法でのの位というのは、の値のことを指す。なので、はじめにの値はで持って良い。
ここからの議論があいまいだが、ある程度大きい定数に対して
である。よって、の値がいくつか分かれば答えが求まることになる。具体的には、
- ならば
- ならば
- かつ ならば
- かつ ならば
- かつ ならば
- かつ ならば
となる。あとは計算して、最後にで割った余りを出力すればよい。例外的に、かつの場合は場合分けを通さずに実際にを計算した。
計算量は、。
C - String Invasion
手元で実験してみると、ある場所でaab
のような並びがあった場合連鎖的に操作が行え、文字列の末尾まですべてa
で置き換えることができる。また、aab...ccd...
というように2か所以上操作が行える箇所が存在した場合、より後ろにあるものから操作しても解は悪化しない。よって、文字列を後ろから見ていくことにする。
ある文字が連続していた場合、基本的にはその箇所より後ろにある文字全てが操作によって置き換わることになる。1回の操作で1文字置き換わるので、文字目と文字目が連続していた時、回操作を行える。
ただし、連続している文字より後ろに、その文字と同じ種類の文字が存在していた場合は操作を行えない。ただしそこで操作の連鎖がストップするわけではなく、それより後ろにある違う種類の文字に対しては操作できる。つまり、「文字目より後ろにある文字のうち、文字と文字の種類が同じである文字の個数」回は操作を行えない。この文字の個数は、「文字の種類」から「個数」を引ける構造を用意しておくことで簡単に調べられる。
以上の操作を文字列の後ろから実行して答えをカウントしていく。計算量は、文字の種類数をとして。
D - Sky Reflector
列A、Bを決めたときに矛盾なく数を埋められるか?を考えるとわかりやすい(と個人的に感じた)。
問題文の条件を言い換えると、
- 行に書き込める整数は以上以下
- 列に書き込める整数は以上以下
となる。さらにまとめると、
- マスに書き込める整数の範囲は以上以下
であることがわかる。
つまり、列の最大値をと固定すれば、各に対してが成立する。個ある要素はそれぞれ独立である。よって、最大値がであるような列の個数をとすると、をすべてのに対して求め、その総和を取ったものが答えとなる。ここでの計算量は、。
を求める。の値は以上以下なら何でもよいが、どれか1個以上はでなければならない。よって、
を満たすに対して、が成り立つ。ここでの計算量は、。
まとめると、全体の計算量は、となる。
…ただし、(または)の場合は例外で、マスに書かれた整数はなので、がすべて決まればの値も決まる。よってこの場合の答えはとなる。この場合分けを忘れて、コンテスト時間内のACを逃した…。(コンテスト後に気付いて場合分けを追加して提出したところ、ACした)くやしい。くやしい!!!!
感想
マジで悔しい~~~~
AtCoder Regular Contest 112参加記(~B問題)
スーパー場合分けコンテスト(ABのみ)
A - B = C
に変形すると負の値が登場しないので考えやすい。
各整数の下限がだった場合、を固定するとは通りとなる。この組の中でが未満のものは組、が未満のものも組あるので正しい答えはとなる。
これをすべての以上以下の全てのに対して求めるとよい。
B - -- - B
公式解説ではの偶奇で場合分けして考察していたが、僕はの正負(とゼロ)で丁寧に場合分けしてそれぞれの答えを書いた。
その中でさらに、よりでかくなるパターン、以上以下になるパターン、より小さくなるパターンにわけるとそれぞれの答えが簡単に求められる。
以上以下になるパターンの考察をミスして1WA。しょうもない。
C - DFS Game
部分木ごとに考えてよい。というところまではよくて、ある頂点から見た子の結果のうち何がわかれば部分木の答えが求まるのかがわからなかった。説明がふんわりでごめんなさい。理解してないからね。
その部分木に突入して戻ってきたとき、「片方が獲得できるコインの数」「もう片方が獲得できるコインの数」「戻ってきたときに次に子を選ぶ権利があるのは自分かどうか」みたいな情報があれば求められそうだった。が、これらの情報が子から複数来るので、何かの基準に合わせてソートしたりして選ばなければならない。わからない。