はじめに
こんにちは。nsubaruです。
直近3回のABCでレートが-66となってしまい、次この記事を書くときは入水したときかなと思っていたのですが、全然そんなことはありませんでした。 ただ自分が負け越している間に当サークルに緑コーダーが2人も増えて大変喜ばしいことだなと思っています。 まあそんな緑コーダーたちに今回は久々に勝てたのでこの記事を書いています。
結果サマリ
-
WCPC参加人数: 7人
-
各問題の最速解答者(ペナルティ無し):
| 問題 | 参加者名 | タイム | 言語 |
|---|---|---|---|
| A | Twil3 | 0:42 | Rust |
| B | kotomiko | 2:38 | C++ |
| C | kotomiko | 27:43 | C++ |
| D | nsubaru | 13:00 | Java |
| E | nsubaru | 83:09 | Java |
| F | - | - | - |
| G | - | - | - |
今週の出題
ABC466-A
問題文を表示
問題文
個の選択肢があります。
あなたは、これらの中から つの選択肢を選びます。あなたが 番目の選択肢を選んだときの嬉しさは です。
どの選択肢を選んでも嬉しさが負になる場合は Yes を、そうでない場合は No を出力してください。
制約
- 入力される値はすべて整数
入力
入力は以下の形式で標準入力から与えられる。
出力
問題文中の指示に従って Yes、No のいずれかを出力せよ。
全ての要素が条件をみたすかどうかを求める問題です。
単純な問題なのでそこまでどうでも良いのですが、コーディング速度向上のために↓のような1行コードを速く書きたいのですが、なかなかベストなコードが書けませんね。
Rustはこんなコードが書けそうなことはこの前知ったのですが、他の言語ではどう書くのか少し気になります。
コードは一部抜粋です(Java)。
// 提出したコード
out.println(IntStream.range(0, n).filter(_ -> sc.nextInt() < 0).count() == n);
// もう少し短く書ける!
out.println(IntStream.range(0, n).allMatch(_ -> sc.nextInt() < 0));
ABC466-B
問題文を表示
問題文
個のボールがあります。
番目のボールの色は 、大きさは です。ここで、色は の整数で表されます。
について、色 のボールの大きさの最大値を出力してください。ただし、色 のボールが存在しない場合は -1 と出力してください。
制約
- 入力される値はすべて整数
入力
入力は以下の形式で標準入力から与えられる。
出力
の順に、色 のボールが存在するならば色 のボールの大きさの最大値を、存在しないならば -1 を空白区切りで出力せよ。
mapを使って解く問題です。毎回B問題はこれくらい単純な問題を置いてくれたらいいのですが。
解法は-1で初期化したサイズの配列を用いて解きます。 mapでも配列でも解法は変わりません。色をインデックスに、大きさを値として最大値を更新していくことで解けます。
ABC466-C
問題文を表示
問題文
この問題は インタラクティブな問題(あなたが作成したプログラムとジャッジプログラムが標準入出力を介して対話を行う形式の問題)です。
数直線上に、点 , , , が この順に 左から右に並んでいます。
最初、あなたには整数 のみが与えられます。
その後、あなたはジャッジに以下の質問を 回まで行うことができます。
- を満たす整数 を選び、点 と点 の距離が 以下であるか質問する。
距離が 以下の 点組の個数、すなわち をみたす整数の組 であって、点 と点 の距離が 以下であるようなものの個数を出力してください。
制約
- は整数
入出力
最初に、点の個数を表す整数 を標準入力から受け取ってください。
次に、あなたはジャッジに対して問題文中の質問を 回まで繰り返すことができます。
質問は、以下の形式で標準出力に出力してください。 ここで、 は を満たす整数である必要があります。
?
これに対する応答として、以下のどちらかが標準入力から与えられます。
Yes
No
ここで、Yes ならば点 と点 の距離が 以下であることを、No ならば点 と点 の距離が より大きいことを表します。
問題の答え が求まったら、解答を以下の形式で出力してください。 その後、ただちにプログラムを終了してください。
!
インタラクティブな問題!?となり、2秒くらい問題を見た後すぐにD問題に行きました。
実際、解法も全く思い浮かばず二分探索…?となっていました。
その後も考察に時間がかかり、左側を基準にして右側を二分探索、その後に右側を基準にして左側を二分探索する…あれしゃくとり法じゃねってなりました。
この間約20分程度で本当に時間を無駄にしました。
そのうえ、実装したしゃくとり法には無駄があったらしく質問数がを越えてしまっていたようで、2WAになり散々でした。
くらいにしてくれれば良かったのですが。ひとまず解けたので良しです。
ABC466-D
問題文を表示
問題文
行 列のマス目があります。
最初、マス目の上には何も置かれていません。
その状態から始めて、高橋君がマス目に対して 回の操作を順に行います。 回目 の操作は以下のとおりです。
- 上から 行目のマスに置かれているコマをすべて取り除く。
- 次に、左から 列目のマスに置かれているコマをすべて取り除く。
- 最後に、上から 行目かつ左から 列目のマスにコマを置く。 回の操作の後でマス目に置かれているコマの個数を出力してください。
制約
- 入力はすべて整数
入力
入力は以下の形式で標準入力から与えられる。
出力
回の操作の後でマス目に置かれているコマの個数を出力せよ。
圧倒的にCより簡単なDでした。
コマを置くという操作と、そのコマとおなじ行と列のコマをすべて取り除くという操作を回行う問題です。
まず、コマを置いたときそのコマが後々消される可能性があるなと考えます。 その次に、一番後ろのコマに注目すると、このコマは削除されず、その行と列にこれまで置いたコマは全て削除されるということに気が付きます。
ここまで考えるとコマを置く順番を後ろから見ることで、コマを置いたときにそのコマが最終的に残るものなのかを判定していくことができます。
ABC466-E
問題文を表示
問題文
枚のカードが並んでいます。カードには の番号が付けられています。
カード の表面には整数 が、裏面には整数 が書かれています。はじめ、すべてのカードは表面が上を向いています。
あなたは、以下の操作を高々 回行うことができます。
- なる整数 を選ぶ。 なる各整数 について、カード を裏返す。ただし、カードを裏返すとは、操作を行う前に下を向いている面を上に向けることを指す。
操作を終えた後、各カードの上を向いている面に書かれている数の総和として考えられる最大値を求めてください。
制約
- 入力される値はすべて整数
入力
入力は以下の形式で標準入力から与えられる。
出力
答えを出力せよ。
ぱっと見難しそうだなという問題でした。
制約ということから、のDPかなという前提で考えました。
まず考えたことは、の解がになったときにどのように遷移するのかみたいなことを考えました。 しかし、だとしてもどの区間を反転させる必要があるかを愚直に求めることができないなと思い、を増やしていくようなDPではないことが分かりました。
なら、の先頭から分割数がを超えないように値を最大化していくみたいに考えます。 紙に書いて考えたらわかりやすいのですが、どの区間が表か裏かを考えるとこの表と裏の区間は最大でも 個しかないことが分かります。
あとはそれを前からDPするだけなので実装は簡単に出来ました。
最後に
C問題で面喰らいましたが、久々に勝てて良かったです。
まだまだ精進不足でE問題も得意不得意が多く、あと少しで水色が結構遠いなという感触です。 ICPCも終わりAtCoderにかけれる時間も増えたので、これを期にレートマイナス月間に終止符を打てたらなと思います。
あとサークルメンバーみんな強くなりすぎているのでそろそろ抜かれそうで怖いです。