Toy と帽子と ADP BE

主にプログラミングに関わる話をゆるくエモくやっていきます

AtCoder Grand Contest 036

1完3WA。まあAGCですし。

各問題

A - Triangle

二次元平面上の(0, 0), (x1, y1), (x2, y2)を頂点とする三角形の面積は|x1 * y2 - x2 * y1| / 2で求められます。(私はググりました)

Sが与えられて面積はS / 2ということなので、S = |x1 * y2 - x2 * y1|ということになります。あとはそれを満たすようなx1, y1, x2, y2を適当に求めればいいです。

私はSの平方根を求めて端数を払った後+1してそれをx1とy1として、次にS - x1 * y 1 == x2 * y 2を満たすようにx2, y2を決めました。 (最初の平方根を切り上げではなく、無条件に+1したためS=1018のとき109+1になってしまってWAをひとつ余計に出してしまいましたが・・・。)

公式解説によると、(0, 0), (1000000000, 1)と置いちゃうんですね。

B - Do Not Duplicate

TLE解しか書けずじまいでした。

周期があると思って実装していたのですが、実装がヘボいのか、周期が思ったより長いものがあるのかその両方か、といったところなんでしょうか?

公式解説によると、ダブリングなるものを使うそうで・・・。ほふー。

C以降

見てません。

まとめ

  • ダブリングを勉強する

AGCで初めて水色パフォを出してHighest更新。次回青パフォなら昇級できるところまで来ました。

早く水色になりたーい。

f:id:mdstoy:20190722003808p:plain

AtCoder Beginner Contest 134

ABCEの4完。Dはバグが取り切れずー。

各問題

A - Dodecagon

問題文に沿って、3 * r * r を計算するだけです。

こんなシンプルな問題が出たの、久しぶりでは?

B - Golden Apple

一人の監視員が監視できる本数は2 * D + 1です。そこからN本の木に対して何人監視員が必要になるかを割り算で求めるだけです。答えを切り上げることに注意。(つまり、intでの/除算が切り捨ての言語はちょうど割り切れる時に気をつけないといけないことに注意。)

え、これA問題でもおかしくないのでは?今回簡単セットなのかな?

C - Exception Handling

数列の中の最大値を、複数の項が持っている場合、いずれかの最大値を抜いても他の最大値が残ります。なので、どの項を除こうが最大値は常に同じ(数列中の最大値)です。 最大値が単独の場合、その項を抜いた場合だけは二番目に大きい数が最大値になります。

最大値とその項番は、入力を取得する時に容易に保存しておけますし、二番目に大きい数は数列をソートすれば容易にとれます。(editorialの方針1もその方法ですね)

D - Preparing Boxes

iが大きい方から見ていけば、すべての箱に対してボールを入れるか入れないかを決定することが可能です。 D問題なのに計算量についてはそれで問題ありません。i == 1のときはN個見ないといけませんが、上半分については自分自身しか見る必要がありませんからね。

とか言いつつ、私は実装をバグらせてしまい、コンテスト中にデバッグしきれませんでした。on_

(追記)

デバッグした結果はこれでした。

そんなミスするか常識的に考えて!?on_

E - Sequence Decomposing

editorialにはLISってありましたが、私はそれ系の知識を持ち合わせていないので、ごりごり実装しました。(勉強しないと)

説明はしにくいんですけど、実装は単純なのでとりあえず見てください。(えー)

https://atcoder.jp/contests/abc134/submissions/6467438

要するに、待ち受けしている数字に繋げられるなら繋げる(その際できるだけ大きい方に繋ぐ)、そうでなければ自身を新しい待ち受けにする、を繰り返して、最終的に待ち受けしている数字の個数が答え、としました。

(追記:YouTube解説と全く同じ考え方でした! なんか嬉しい)

ところで自分はvectorで実装したんですけど、こういうこときにmultisetを使うんですね。

あと、ソート済みのvectorに対しては、push_backして改めてsortするより、挿入位置を探してinsertするほうが速いということを身をもって知りました。

ダメな実装

            if (x == q.begin()) {
                q.push_back(a);
                sort(ALL(q));
            } else {
                q.erase(x - 1);
                q.push_back(a);
                sort(ALL(q));
            }

ましな実装

            if (x == q.begin()) {
                auto x = upper_bound(ALL(q), a);
                q.insert(x, a);
            } else {
                q.erase(x - 1);
                auto x = upper_bound(ALL(q), a);
                q.insert(x, a);
            }

F - Permutation Oddness

まったく考察できず。

まとめ

  • コンテナに関する知識をアップデートした
  • LISとかそういう系統の知識が全く無いので勉強しないといけない
  • 最後慌てすぎた・・・

まあ一月ぶりにHighestを(2点だけですが)更新できたので、とりあえずよし。

f:id:mdstoy:20190721010501p:plain

AtCoder Grand Contest 035

1AC5WA。ひどいけど、まあ実力ですか。

各問題

A - XOR Circle

最終的には「全部0」または「nが3の倍数かつ3つの数字(これらは重複していてもよい)が循環している形で、その3つの数字で題意を満たせる場合」が"Yes"、という解答にたどり着きましたが、そこにたどり着くまでが長かった・・・。

全部0というのにも最初気づけなかったし、3つずつ循環していてもよいということにもなかなか気づけなかったのです。 5つもWAを投げているのは、明らかに極端な誤答(例えばn != 3なら無条件で"No"にするとか)を投げて、WAの傾向がどう変化するかを見て対策を立てるという緊急手段をとったためです。 今回に関しては、n == 3でなくても"Yes"になるケースがあると気づけたので、全く無駄にはならなかった模様。ペナルティーは痛いですがやむなし。

B - Even Degrees

一応考えていたのですが、その考察は的はずれだった模様。明らかに構築できるケースでも、それを復元する方法を思いつけなかったので論外ですが。

C以降

見てません。

まとめ

緑コーダーにAGCはきついという、当たり前の結果でした。

まあなんとかAだけでも通してレート微減で済んだのでいいかな、と。水色一発圏内からは遠のいてしまいましたが。

f:id:mdstoy:20190715002501p:plain

AtCoder Beginner Contest 133

4完3WA。あーなんか通常運行に戻ってしまった感が・・・。

各問題

A - T or T

最初、タクシーと電車に分乗するケースがあるのかと思って、A問題にしては難しくない?B問題と間違ってる?と思ったんですが、よく見るとタクシーにはN人全員が乗れることから、A * NBの比較だけでよかったんですね。それにしてもでかいタクシーだな

B - Good Distance

二重ループ(計算部分を入れれば三重ループ)を回して全通りを実際に計算してみればいいです。私はtypo連発してめちゃくちゃ時間がかかってしまいました。

C - Remainder Minimization 2019

結論からいうと、mod 2019なのでiとjそれぞれたかだか2019個について検査すればよくて、最大でも2019 * 2019個を調べれば答えが求まります。

私はなにを血迷ったかmod 2019が最小になるiとjを「別々に」探してから掛け算していて、しかも2019が素数だと思いこんでいて(どう見ても3の倍数です本当にry)、2WAを出してしまいました。

D - Rain Flows into Dams

山1に降った雨をM1、山2に降った雨をM2とします。A1 = M1 / 2 + M2 / 2です。同様に、A2 = M2 / 2 + M3 / 2A3 = M3 / 2 + M4 / 2と循環していきます。このN元1次の連立方程式を、ぐるーーーんと順番に解決していくと、最終的にM1が求まります。M1が求まれば、順次M2以降も求まりますね。

私はintで足りると判断してたら1WA喰らいました。どこでオーバーフローしたのだろう?

E - Virus Tree 2

必死に数え上げの方法を考えていましたが、シンプルなケースでしかわからずタイムアップでした。

今、editorialを見て膝から崩れ落ちているところです。問題の言い換えをする技術がなさすぎるよ自分・・・。

F - Colorful Tree

そっとじ。

まとめ

問題を言い換える技術なぁ・・・。わかっていてもなかなかできません。知識の問題もあるし頭の固さの問題もあるし時間に追われて焦ってしまうという問題もあります。そこをなんとか克服しないといけませんね。

結局、知識をつけていくしかないかなぁまずは。

で、今回レート増減なしでした。水色を前にして収束し始めてる?まずくない?

f:id:mdstoy:20190707231232p:plain

AtCoder Beginner Contest 132

ABCの3完で、気分的には大惨敗ですね。今回は水色入りを狙っていただけに。

各問題

A - Fifty-Fifty

問題の意味はわかるんですけど、最短の実装法がすぐに浮かばず。

そこで悩んでいても時間がもったいないので、最初に浮かんだ方法、アルファベットの数の26要素のint配列を作って、出現した文字の要素をインクリメントして、最後に26個それぞれ要素がすべて0か2ならYes、それ以外の数が入っていればNoという実装をしました。ループが必要になるので、たぶんちょっと回りくどい実装のはずです。

あーでもeditorialの解法も(A問題にしては)思ったほど軽くはないですね。

B - Ordinary Number

愚直に{p1, p2, p3}, {p2, p3, p4}, ... と見ていけばよいです。ちなみに私はmaxでもminでもないとき条件を満たす、という実装をしました。不等式怖い・・・。

C - Divide the Problems

まず入力を取ってきてソートします。

で、真ん中のふたつ、つまりN / 2番目とN / 2 + 1番目の数が同じである場合、きれいに半分に分けることはできません。その数がどっちか片方に入るので偏りが出ます。なのでこの場合は0です。 異なる場合、単にそれを引けば答えになります。

ていうか今気づいたんですけど、真ん中のふたつが同じ数のとき、引いたら0になるから結果的には場合分け要りませんでしたねこれ。まあこういうケースが例外的な値になってWAをもらうこともあるので、あらかじめ考察しておくのは悪いことではない、はず。

D - Blue and Red Balls

ふんわりとはわかったんですけど、きっと使うはずと思ってnCrのライブラリもコピペしたんですけど、組み合わせの作り方が結局最後までわからずじまいでした。なさけない。

EとF

チラ見しただけ。

まとめ

相変わらず数学力のほうがネックになっているような気がします。あと、不得手な領域がまだまだ多いので安定しません。今後は苦手な問題を集中的に潰していったほうがいいのでしょうか・・・。

3完なのにパフォ4桁に乗っていて、レートは微減で済みました。Cまでの早解きはできていたのでなんとか助かった感じです。

f:id:mdstoy:20190629233108p:plain

AtCoder Beginner Contest 131

5完で、初の青パフォ。前回のレート減少をのしつけて返してやりました。

各問題

A - Security

単純に隣り合う文字を比較していって、同じものが一つでもあるなら"Bad"、一つもないなら"Good"です。 ループを回してもいいし、4文字限定なのでif文3つ並べてもOKですね。

B - Bite Eating

ひとつだけ抜くリンゴは絶対値が一番小さいものにすると題意を満たすので、それを探して、すべてのリンゴの味の和から抜くリンゴの味を引けばいいです。

C - Anti-Division

「割り切れないもの」の数は全体の数から「割り切れるもの」の数を引けばいいです。

「割り切れるもの」の数は、Cの倍数の数 + Dの倍数の数 - CとDの公倍数の数、です。Cの倍数の数 + Dの倍数の数だけでは、CとDの公倍数についてダブって数えてしまうことに注意。(包除原理)

求めるのはA以上B以下の整数についてなので、B以下についてとA「未満」についての「割り切れないもの」の数を求めて、前者から後者を引けばいいです。A「未満」にしないとちょうどAのときが抜け落ちてしまうので注意です。(私はサンプルに該当するケースがなかったらやらかすところでした・・・)

D - Megalomania

締切時間でソートしてから、前からひとつずつ確認していけばOKです。

ソース見てもらったほうがわかりやすいかも -> https://atcoder.jp/contests/abc131/submissions/6062745

これ、Cの300でもいいのでは?

ちなみに、editorialの実装のようにAとBを逆に格納するとsortの比較関数を書かなくて済むのですが、私はあとで混乱する可能性があるので避けるようにしています。 変数名をわかりやすく付ければいいだけの話なんですけど、競プロの場合その手間を惜しんじゃうんですよね。

E - Friendships

Kが取りうる最大値はN * (N - 1) / 2 - (N - 1) です。これがどういう状態かというと、例えばN=5のとき

  2
  |
3-1-4
  |
  5

こういう状態です。(いわゆるスター) この場合、2-3, 2-4, 2-5, 3-4, 3-5, 4-5 の6つの距離が2です。 あとは、ここから辺を一つ足すごとに距離が2の2点が一つ減っていくので、与えられたKに合うように辺を適当に足せばよいです。

結構最近に、すべてのN * (N - 1) / 2個の辺がある状態から題意に合わせて間引いていくという問題が出題されていたのを覚えていたので、割とすんなりこの発想に至れました。復習は大事ですね。

F - Must Be Rectangular!

私はx座標ごととy座標ごとのmapを用意して愚直に探す、ということをやろうとしたのですが、おそらく嘘解法な上にTLEも出ていました。とほほ。

あとでeditorial読んで勉強します。

まとめ

当たり前ですけど、復習は大事。超大事。

初の青パフォで超回復達成。次回も同程度のパフォならレート水色になるので、昇格戦ということになります。頑張る。

f:id:mdstoy:20190622230041p:plain

AtCoder Beginner Contest 130

2完。ちょうど20回目の参加になりますが、今までで一番ひどい成績(パフォ)でした。そんなことある?!

各問題

A - Rounding

XとAを比較して0と10を出し分けるだけです。

しかし、cin >> X >> A;cin >> X, A と書いてしまい1WA。 波乱の立ち上がり・・・。

B - Bounding

L を順に足していって、Xを超えないところまでの回数+1(D1=0のときの分)が答え。

しかし、回数を足す処理を記述する位置を間違っていたためコーナーケースに引っかかりまた1WA。 ぐぬぬ・・・。

C - Rectangle Cutting

考え方がそもそも間違っていて問題外。(対角線上にあれば対角線に切る、それ以外は縦か横に切る、だと思ってました・・・。)

本当に幾何は苦手なんです・・・。

D - Enough Array

累積和を取ってしゃくとり法でOK。和がK以上になる位置が見つかったとき、それより後ろが全て条件を満たすので、N - 見つけた位置 + 1を合計に足していくのがみそ。

なのですが、なぜかWAがなくならない。コンテストが終わってから見直したら、一部の変数をintで定義していたという。long longに直したら一発で通りました・・・。

400点損した。これはひどい。ひどすぎる。

E と F

C, Dがご覧の有様だったので、チェックすらできず・・・。

まとめ

とりあえず落ち着きましょう。

あと、実は調子が悪いことは自覚していたので、休む勇気を持つべきだったかもしれないです。コンテストの参加は義務ではないですしね。

AGC以外では初めてのレート減少で1000割ってしまいました。まあ続けていればたまにはそういうこともあるかなくらいに思っておくことにしましょう。 Dはありがちなミスで400点失ってしまいましたが、解法はちゃんとあっていたわけですし。まあそう悲観することもないかな、と。

f:id:mdstoy:20190616233200p:plain