ganmo::cout

競技プログラミング始めました

KEYENCE Programming Contest 2019

ABCDの4完438位を果たし、ビギナーコンテスト以外で初めての青パフォ(1708)を獲得した!実験だいじ。

A - Beginning (100点)

問題: A - Beginning
順番が関係ないので、4つの数字を小さい順にソートして、[1, 4, 7, 9]になっていればYESを出力する。

拙解 (C++):
Submission #3998594 - KEYENCE Programming Contest 2019 / キーエンス プログラミング コンテスト 2019

B - KEYENCE String (200点)

問題: B - KEYENCE String
正しくスマートな解法に到達するまでに4WAを連打してしまった(反省)
Sの両端から何文字 "keyence" に一致するかを数えて、合わせて |"keyence"| 以上ならば中をくりぬいて "keyence" が作れるので、YESを出力する。どちらか一方が0でも片方が7以上つまり完全に一致していればYESなことに注意する…という問題かと思っていたが、どうやら「…keyence」「keyence…」の形のテストケースはなかったらしい*1

拙解 (C++):
Submission #4002299 - KEYENCE Programming Contest 2019 / キーエンス プログラミング コンテスト 2019

C - Exam and Wizard (400点)

問題: C - Exam and Wizard
なかなか手こずった。しかし、色々実験して「順番は関係ない」「足りない分は否が応でも変えざるを得ない」ということに気づくと、「余剰分が大きいほうから配分を割り振る」という貪欲で通った。
具体的には、まず新しい配列{V_i:=A_i-B_i}を作ってソートし、累積和を取っておく。lower_boundで0以上の最初の項を探してそれ以前の負の項の総和(=足りない分)が、大きいほうから何項の和で賄えるか、というのを一つずつ見ていくと、{O(N)}で解ける。

拙解 (C++):
Submission #4005842 - KEYENCE Programming Contest 2019 / キーエンス プログラミング コンテスト 2019

D - Double Landscape (500点)

問題: D - Double Landscape
BとCで時間とWAを大幅に食ってしまい、終了30分前に取り掛かった時点でac-predictorが緑パフォを指し示しており、これはやばいと思いつつ解いた。結果解けたので良かったが…
これは紙とペンを駆使して解いた。
まず、最大値が制約になっているので、より大きい値がより制約が多い。列と行の順番は関係ないので、\{A_i\}\{B_i\}をソートする。したがって大きい値NMから始めて、一番最大値の大きい右下のところから書き始めるのがいいとわかる。
そして、今書こうとしている値Kが書き込める範囲(つまり{K \le A_i \land K \le B_j})を見たとき、その左端の列・上端の行が等しいかどうかによって4通りの場合分けができる。

  • 1. {K=A_i \land K=B_j}のとき

 前の値と比べて範囲は左上に1行1列広がるので、書き込む場所は(i, j)一択。

  • 2. {K=A_i \land K< B_j}のとき

 前の値と比べて範囲は新しく上に1行広がるので、書き込む場所はその広がった範囲の(M-j)択。

  • 3. {K< A_i \land K=B_j}のとき

 前の値と比べて範囲は新しく左に1列広がるので、書き込む場所はその広がった範囲の(N-i)択。

  • 4. {K< A_i \land K< B_j}のとき

 前の値と比べて範囲は同じで、新しく広がったりはしない。すでに{MN-K}個の数字がその範囲に書き込まれているので、{(M-j)(N-i) - (MN-K)}択。

以上1.~4.の場合の選択肢はすべて独立で、どこでどれ選んだから何択か変わることはないので、pを法としつつ全部掛けていくと答えが出る。

拙解 (C++):
Submission #4008495 - KEYENCE Programming Contest 2019 / キーエンス プログラミング コンテスト 2019

E - Connecting Cities (600点)

問題: E - Connecting Cities

終了5分前にできそうかなーとか無謀なことを思ったがサンプルケースすら通らず終了。そりゃそうだ。
Editorial曰く枝刈りをして最小全域木を求めるらしい。

まとめ

初めてコンテスト本番中に500点問題をACして青パフォを出した。
まず愚直解を書いて色々実験をして法則性を掴む、という手法がとても有効であることが分かった。

*1:そのため、これらのテストケースを考慮せずに中抜き型しか考慮しない嘘解法でもACになるようだ