はじめに
こんにちは、Caffeineholicです。今回のABCは4完にとどまりました。 最近いくつか並行して個人的に記事を書いていますが、書いているうちに楽しくなってきました。 その勢いのままこの記事も書ききってしまいます。参加記を書けていない回は他のメンバーが埋めてくれることを信じて。
成績としては、4完となりました。E問題が難しかったようです。 E問題を解ききっている人がとても少ないことが本番中の順位表からわかったので、ちらっと問題を見ただけで解かずに戻りました。 判断としては正解だったようです。体感難易度としては A < B << D < C でしたね。
D問題までの所感を載せておきます。
結果サマリ
- ABC483
- WCPC参加人数: 5人
- 各問題の最速解答者(実AC時刻):
| 問題 | 参加者名 | タイム | 言語 |
|---|---|---|---|
| A | nsubaru | 0:33 | Java24 (OpenJDK 24.0.2) |
| B | nsubaru | 3:55 | Java24 (OpenJDK 24.0.2) |
| C | nsubaru | 29:41 | Java24 (OpenJDK 24.0.2) |
| D | nsubaru | 65:01 | Java24 (OpenJDK 24.0.2) |
| E | - | - | - |
| F | - | - | - |
| G | - | - | - |
今週の出題
ABC483-A
問題文を表示
問題文
正整数 が与えられます。
ページからなる資料をコピー用紙に印刷します。
印刷には両面印刷を使い、コピー用紙 1枚の表と裏にそれぞれ ページずつ印刷することができます。
ページを全て印刷するために必要なコピー用紙の枚数の最小値を求めてください。
制約
- 入力される値は整数
入力
入力は以下の形式で標準入力から与えられる。
出力
答えを出力せよ。
ページまたは ページの資料なら3枚の用紙に印刷できます。 ページまたは ページの資料なら 枚の用紙に印刷できます。 私は計算ミスで焦ることを恐れてif文を使ってゆっくり書きましたが、最短で書くならこうです。
n = int(input())
print((n + 1) // 2)
ABC483-B
問題文を表示
問題文
から までの番号が書かれた(表裏の区別できる) 枚のカードがあり、 最初、上から の順ですべて表向きで積まれています。
高橋君はこの山に 回の操作を行います。 回目()の操作では以下の操作を行います。
上から 枚のカードをひとまとめにして裏返し、元の位置に戻す。
これにより、上から 枚のカードの順序が上下逆になり、それぞれのカードの表裏も反転する。
すべての操作を終えた後のカードの順序と表裏を求めてください。
具体的には、 について、上から 枚目に置かれているカードに書かれている番号が のとき、そのカードが表向きで積まれている時 を、裏向きなら を出力してください。
制約
- 入力はすべて整数
入力
入力は以下の形式で標準入力から与えられる。
出力
行出力せよ。 行目()には、 回の操作の後で上から 枚目に置かれているカードに書かれている番号が のとき、そのカードが表向きで積まれている時 を、裏向きなら を出力せよ。
Python使いはデータ構造Listに対してスライスという操作を行えるのでより簡単になりますが、各カード情報を配列に記録してfor文を使って作り直していくという操作で、比較的単純に解けるかと思います。 B問題らしいB問題でした。グリッド関連の問題が出ると焦りやすいので良かったです。
ABC483-C
問題文を表示
問題文
AtCoder 村で村長を決める投票を行うことになりました。
候補者は 人おり、候補者 , 候補者 ,, 候補者 と番号づけられています。
投票者は 人おり、 人目 の投票者の投票先の第一希望は候補者 、第二希望は候補者 です。
候補者のうち一人のみが辞退した時、それぞれの投票者は以下のように投票します。
- 第一希望の候補者が辞退していなければ、第一希望の候補者に投票する。
- 第一希望の候補者が辞退していれば、第二希望の候補者に投票する。
辞退していない候補者のうち、得票数が最大の候補者が当選します。そのような候補者が複数いる場合は、番号が最小の候補者が当選します。
それぞれについて、候補者 のみが辞退した場合に当選する候補者の番号を求めてください。
制約
- 入力はすべて整数
入力
入力は以下の形式で標準入力から与えられる。
出力
行出力せよ。 行目には、候補者 のみが辞退した場合に当選する候補者の番号を出力せよ。
僕たちが計算量マジックと呼んでいる類の問題です。 一見不可能な回数の操作が必要であるように見えて、考察を進めると愚直にシミュレーションできることに気づくというものでした。 こういう問題には出るたびに敗北を喫していますが、今回はSegmentTreeに二次元の情報を詰め込むというリッチな手段で解ききりました。
弁解をしておくと、途中から愚直なシミュレーションが通るという考察には至っていました。が、最初に書いた方法でも正解できるという自信があったためにその書き方に固執して、結果デバッグにかなりの時間を費やすことになってしまいました。 C問題に50分ほどかかりました。
ABC483-D
問題文を表示
問題文
数直線上にロボットがいます。はじめ、ロボットは座標 にいます。 また、高橋君は長さ の整数列 を持っています。
高橋君は次の操作を行います。
1. の要素を 高々 つ 選び、その符号を反転させる。すなわち、 をみたす を または つ選び、 を に書き換える。
- ロボットを起動する。ロボットは起動後、 回の行動を行う。 回目 の行動では、現在の座標を として、座標 へ直線的に移動する。
高橋君はロボットが一度以上通る整数座標の個数をなるべく多くしたいです。
高橋君が最適に行動したときの、「ロボットが一度以上通る整数座標の個数」としてあり得る最大の値を求めてください。
なお、ロボットは連続的に移動するものとし、ある移動で座標 から まで移動したとき、 ならば 以上 以下の任意の整数座標、 ならば 以上 以下の任意の整数座標を通ったとみなします。
制約
- 入力はすべて整数
入力
入力は以下の形式で標準入力から与えられる。
出力
高橋君が最適に行動したとき、ロボットが一度以上通る整数座標の個数としてあり得る最大の値を出力せよ。
動きのイメージが付けば実装を頑張るだけという問題だったと感じています。
回目の移動の正負を反転させても 回目以降の移動の仕方は変わらないことに気づくことが大切です。 左右への移動の仕方は変わらずその基点が の反転によって変わるだけ。 だから、 回目までと 回目以降とについての累積minと累積maxを利用して、仮に 回目の移動を反転した際に最終的な左右差がどれだけできるかを計算しました。
E問題以降は、割愛とさせていただきます。
最後に
今週もお疲れさまでした。 そろそろサイトのデザインを改修したいです。
Caffeineholicでした。