こんにちは!アルゴリズム班の@noya2 @ebi @shobon @0214sh7 @Sotatsu です。
この記事は2023年4月26日に行われたCPCTF2023 のPPC部門の作問陣writeupです。
目次
Newbie
Easy
Medium
Hard
Newbie
Count Coins
作問者: @ebi
AC者数
ヒントなし | ヒント1 | ヒント2 | ヒント3 |
---|---|---|---|
56 | 0 | 0 | 3 |
問題文
すくくんは 枚のコインを格納できるコインケースを持っています。
始めに 枚のコインを持っています。
すくくんは次の つイベントのうちどちらかが 回連続で発生します。
- イベント : コインを 枚得る。すでにコインを 枚持っている場合は 枚のままとなる。
- イベント : コインを 枚失う。持っていたコインが 枚未満のときは 枚になる。
回目のイベントが であるとき、すくくんは 回のイベント終了後にコインを何枚持っていますか?
制約
- 入力はすべて整数
解法
各イベントをシミュレーションすることで、 回のイベント終了後のコインの数を求めることができます。
すくくんが持っているコインの数を としたときのシミュレーションの疑似コードは以下のようになります。
for i in range(n):
if a[i] == 1:
x = min(10, x + 1)
else:
x = max(0, x - 3)
作者感想
Count CoinsはもともとMario Kartという名前でした。別にレース要素もないし、混乱を招くので変更になりました。
Transfer
作問者: @ebi
AC者数
ヒントなし | ヒント1 | ヒント2 | ヒント3 |
---|---|---|---|
51 | 0 | 0 | 1 |
問題文
東工大に登校だい!するべく、田園都市線で二子玉川駅に来たあなたは大井町線で大岡山駅を目指します。
あなたは以下の つの電車を選べます。
- 各駅停車:今から 分後に来て、 分乗ると大岡山駅に着く
- 急行:今から 分後に来て、 分乗ると大岡山駅に着く
より早く登校だいするために、あなたは大岡山駅に着く最も早い時間が知りたいです。
大岡山駅に着く最も早い時間は何分後かを求めてください。
制約
- 入力に含まれる値は全て整数である
解法
が答えです。
作者感想
東京工業大学は大岡山駅にあるのでそれにちなんだ問題です。
Find cpctf
作問者: @shobon
AC者数
ヒントなし | ヒント1 | ヒント2 | ヒント3 |
---|---|---|---|
32 | 0 | 0 | 1 |
問題文
長さ の数列 と、英小文字からなる長さ の文字列 が与えられます。 の 番目 の文字を と表します。
あなたはちょうど 回だけ次の操作を順に行います。
- を好きなように並び替える。厳密には、 の順列 を つ決め、 を に同時に置き換える。
- すべての に対し、 のアルファベットを 文字右にシフトしたものに置き換えることを 回繰り返す。ただし、アルファベット a, b, c, ..., y を 文字分右にシフトしたものはそれぞれ b, c, d, ..., z であり、z を 文字分右にシフトしたものは a とする。
適切な操作をすることで、操作後の の部分文字列として cpctf を含むようにすることは出来るかどうか判定してください。
ただし、文字列 が文字列 の部分文字列であるとは、 が の先頭から 文字以上、 の末尾から 文字以上取り除くことで得られる文字列であることを言います。
制約
- は整数
- は英小文字からなる長さ の文字列
解法
連続部分列の位置が 通りしかないことに注目して、 を固定してすべて調べます。
各 では を都合よく並べることで をそれぞれ c, p, c, t, f に変えられるかどうかを判定すればよいです。
このときの実装はさまざまですが、 に対して となる の個数を別の配列で管理すると楽です。
作者感想
この問題は PPC の Newbie 以外の最易のうちの 1 つでしたが、それでもかなり難易度に差があるように思いました。プログラミングに慣れていない方は実装が辛かったと思います。
この問題はシーザー暗号・ヴィジュネル暗号を見て思いつきました。
Floor Sqrt
作問者: @noya2
AC者数
ヒントなし | ヒント1 | ヒント2 | ヒント3 |
---|---|---|---|
31 | 2 | 1 | 0 |
問題文
正整数 が与えられます。
次の条件を満たす正整数 の個数を求めてください。
制約
- は整数
解法
実験して条件を満たす を列挙すると、 の形の整数が条件を満たしていることが分かります。 ごとにまとめて処理すると実行時間制限に間に合います。算数をすると 時間で解くこともできます。
作者感想
成り立つか怪しい見た目をしている恒等式っぽいものを探して、問題が出来上がりました。
Geometric Progression Sum
作問者: @noya2
AC者数
ヒントなし | ヒント1 | ヒント2 | ヒント3 |
---|---|---|---|
23 | 0 | 0 | 1 |
問題文
長さ の数列 があり、はじめはすべての要素は です。
整数 が与えられます。今から 回の操作を行なって を更新します。
回目の操作では が与えられます。 の順に次を行なってください。
- に を加算する
回の操作が終了した後の の各要素を で割ったあまりを求めてください。
制約
- 入力はすべて整数
解法
imos法の要領で遷移を 倍にすれば良いです。
作者感想
imos法の応用問題を目指して作りました。git を使って問題管理をしていたのですが、人々のミスが重なりに重なった結果、この問題のbranchが大変なことになりました。
Whisper Sucu
作問者: @0214sh7
AC者数
ヒントなし | ヒント1 | ヒント2 | ヒント3 |
---|---|---|---|
23 | 0 | 0 | 1 |
問題文
ウィスパーすく君は、人間とは思えないほどの低音ボイスとそこから繰り出すハスキーなささやきで有名な声優です。
待ちに待ったASMR音声収録日、なんとウィスパーすく君は寝坊をしてしまいました!これでは収録に遅刻してしまいます!子猫ちゃんたちにときめきを届けるべく、ウィスパーすく君は何としても収録スタジオに行かなくてはなりません!
ウィスパーすく君の住んでいる街は 頂点 辺の無向グラフとして表され、 番目の辺は頂点 と を結んでいます。ウィスパーすく君の家は頂点 にあり、スタジオは頂点 にあります。また辺には信号があることがあり、 番目の辺は以下の 通りのいずれかです。
- のとき、その辺には信号があり偶数分にのみ移動できる。
- 正確には、時刻 から時刻 にかけて辺の一端から他端に移動できる ( は非負整数)
- のとき、その辺には信号があり奇数分にのみ移動できる。
- 正確には、時刻 から時刻 にかけて辺の一端から他端に移動できる ( は非負整数)
- のとき、その辺には信号がなくいつでも移動できる。
ウィスパーすく君は今いる頂点から、辺で結ばれている別の頂点に 分かけて移動します(途中で引き返すことはありません)。ウィスパーすく君は急いでいるので、今いる頂点に留まることはありません。頂点 以外の頂点において他の頂点に移動できないとき、ウィスパーすく君は爆散します。
ウィスパーすく君は時刻 に家を出発しました。ウィスパーすく君の検索アプリであるあなたは、最短で何分でスタジオにたどりつけるか、あるいは爆散するかを判定して下さい。
制約
-
-
-
-
-
与えられるグラフは単純である、すなわち
- ならば
-
与えられるグラフは連結である
- すなわち、どの頂点からどの頂点にも 個以上の辺をたどって移動できる
-
入力はすべて整数
解法
頂点グラフから、頂点番号と時刻の偶奇をもった頂点数 の拡張グラフを作成し、そのグラフ上でBFSを行います。
作者感想
CPCTF22で出題したShout Sucuの続編がついに登場
Shout Sucuはストーリーができてから問題を作ったのですが、今回は問題を先に作ってからストーリーをつけました。このため問題設定が不完全燃焼でした。
解法や作者感想、答えとなるフラグを眺めてると作問者の性格がよくわかりますね。
Digital Clock
作問者: @shobon
AC者数
ヒントなし | ヒント1 | ヒント2 | ヒント3 |
---|---|---|---|
9 | 2 | 0 | 1 |
問題文
しょぼん君は不思議なデジタル時計を持っています。そのデジタル時計は「時間」と「分」をそれぞれ表示する機械で、「時間」は 以上 未満の整数値、 「分」は 以上 未満の整数値を取ります。
デジタル時計に表示されている「時間」「分」は最初ともに です。しょぼん君はそのデジタル時計の時刻を設定しようと思っています。
時刻の設定に使うボタンは 種類あり、それぞれ「時間ボタン」、「分ボタン」という名前です。
-
「時間ボタン」を 回押すと、「時間」の値が 未満なら「時間」の値を 増やし、「時間」の値がちょうど なら「時間」の値を にします。
-
「分ボタン」を 回押すと、「分」の値が 未満なら「分」の値を 増やし、「分」の値がちょうど なら「分」の値を にします。
それ以外で「時間」と「分」の値が変わることはありません。
しょぼん君が時刻の設定に使うボタンを合わせてちょうど 回押したとき、デジタル時計の表示、すなわち「時間」と「分」の組は全部で何通りありえますか?
制約
- 入力は全て整数
解法
到達可能な組は整数 を用いて と表されます。
ここで とすると、 なら は の倍数です。
結局 の で割った余りの種類数を求めればよいので、到達可能な組は 種類であることが示されます。
作者感想
この前に noya2 さんとyukicoderで合同コンテストを開いたときに、ギリギリに出したので間に合わなかった問題です。もともと 解法が想定でしたが、noya2 さんが 解を出してくれてびっくりしました。
実装が軽くてギャグですが、なかなか非自明だと思います。
God Field
作問者: @0214sh7
AC者数
ヒントなし | ヒント1 | ヒント2 | ヒント3 |
---|---|---|---|
13 | 0 | 0 | 0 |
問題文
預言者のあなたは乱闘界に迷い込んでしまいました。預言者たちの戦いが今始まる!
あなたの HP は最初 であり、あなたは 個の防具を持っています。 個目の防具の防御力は です。防具は使い捨てであり、一度使うと壊れてしまいます。
今からあなたは 回の攻撃を順番に受けます。
攻撃には攻撃力があり、 回の攻撃に対し 個以上の防具を使って対抗することができます。攻撃力を 、使う防具の防御力の総和を とするとあなたは のダメージを負い、その分だけ HP を失います。 番目の攻撃の攻撃力は です。
また、攻撃には「無属性」または「闇属性」の属性が付いています。 番目の攻撃の属性は で表され、 のとき無属性で のとき闇属性です。
あなたは以下のいずれかを満たしたとき、昇天してしまいます。
- HP が 以下になる
- 闇属性の攻撃で 以上のダメージを負う
防具を適切な方法で使ったとき、あなたは昇天せずに生き残ることができますか?また生き残れる場合、HP は最大でいくつ残りますか?
制約
- 入力はすべて整数
解法
受けた攻撃の回数が 、使った防具の集合が のとき残る HP の最大値、どうしても昇天するときは
というDPを行うことで答えを得ます。
作者感想
問題設定がおぼろげながら浮かんできたので指数時間解法を与えて問題にしました。
ゴッドフィールドには無・闇属性の他に5つ属性があるのですが、実装が大変になるだけなのでオミットしました。
同じゲームを題材にした問題でもMario Kartは問題名が変更になったのにこっちはなんともありませんでした。どうして・・・
Move Road
作問者: @Sotatsu
AC者数
ヒントなし | ヒント1 | ヒント2 | ヒント3 |
---|---|---|---|
10 | 0 | 1 | 0 |
問題文
縦 マス、横 マスの のマス目を考えます。マス目の各行は道路になっており、車が何台か走っています。
時刻 において、上から 行目、左から 列目のマス は、D のとき車があり、. のとき車がありません。
Sotatsu君は時刻 に、上下左右に隣接するマスに移動するまたはとどまることができます。
しかし、Sotatsu君は車のある道に移動すると車にぶつかってしまいます。
上から 行目の全てのマスはスタートマス、上から 行目の全てのマスはゴールマスであり、これらのマスの上に車はありません。
Sotatsu君は車にぶつかったり、轢かれたりせずにスタートマスのいずれかからゴールマスのいずれかに移動したいです。
時刻 に車は右に マス進みます。右端のマスにいた車は同じ行の左端のマスに移動します。このとき、すでにSotatsu君がいるマスに車が進んでしまうと、Sotatsu君は車に轢かれてしまいます。
Sotatsu君は、時刻 にスタートマスのいずれかから移動を開始します。車にぶつかったり、轢かれたりせずにゴールマスのいずれかまで移動できるか判定してください。
制約
- は整数
- は . または D
- または のとき に D は存在しない
解法
整数時間における車の状態は周期性があり、それはW通りです。visit[t][i][j]
:=時刻を で割ったあまりが のときに、マス に到達できるかという問題を考えます。
これは、BFSやDFSなどを用いて求められますが、このままでは状態数が多すぎます。
車を移動させる代わりに、時刻 が整数のとき常にSotatsu君は左に 移動すると考えます。また、Sotatsu君は左端から出ると同じ行の右端に移動するとします。このようにすることで、車は初期配置から移動させなくてよくなり、「visit[i][j]
:= Sotatsu君はマス に到達することができるか」とすることができ、状態数を にすることができます。
Sotatsu君の移動に常に左に移動することを追加すると、左上 / 左下 / 左 への移動が可能であることがわかります。各移動が可能である条件は以下のようになります。
- 左上:上と左上に車がない
- 左下:下と左下に車がない
- 左 :左に車がない
よってBFSやDFSを用いて時間計算量 でこの問題を解くことができました。
作者感想
鳥が障害物をよけながらピョンピョン進むゲームから着想を得た問題です。
Max Min GCD
作問者: @noya2
AC者数
ヒントなし | ヒント1 | ヒント2 | ヒント3 |
---|---|---|---|
12 | 2 | 0 | 0 |
問題文
長さ の正整数列 が与えられます。
のそれぞれに対して、以下の値を求めてください。
すなわち、 は かつ を満たすすべての整数の組 に対する の最大値です。
制約
- 入力はすべて整数
解法
最大値の最大値という典型テクの紹介です。 の順序を入れ替えることで見通しが良くなります。 の約数を列挙し、条件を満たすindexにchmaxしていくと解けます。
作者感想
最大値の最大値、驚き度高めのテクだと思うので、布教を目指して作りました。
Hop Step Jump
作問者: @noya2
AC者数
ヒントなし | ヒント1 | ヒント2 | ヒント3 |
---|---|---|---|
3 | 0 | 1 | 2 |
問題文
東工大には 個のマスが一列に並んだマス目があり、マスには順に から までの番号がついています。Alice は東工大に新入生が入ってくるので嬉しくて飛び跳ねたい気持ちでいっぱいです。そこで、Alice は次の動作を 回以上行って、Alice のいるマス から traP の部室があることで知られるマス に行くことにしました。
- なる整数 を選ぶ。
- 今いるマスから マス進み、さらに マス進み、さらに マス進む。
Alice はすべての動作を終えた後、マス にいなければなりません。
Alice が経由するマスの集合としてあり得るものは何通りありますか。答えを で割ったあまりを求めてください。
制約
- は整数
解法
母関数が多項式の有理関数になるので、行列累乗で解くことができます。
作者感想
母関数の記事をtatyamさんが書いているので、それの布教のために作りました。
数日前まで Alice の部分は noya だったのですが、noya というハンドルネームの後輩がtraPに加入したため、急遽 Alice に変更しました。
Lost Array
作問者: @shobon
AC者数
ヒントなし | ヒント1 | ヒント2 | ヒント3 |
---|---|---|---|
4 | 0 | 0 | 0 |
問題文
正整数 と素数 が与えられます。
昨夜、しょぼん君は無限項からなる数列 で遊んでいました。しかし今日になって、しょぼん君はどうやって数列 を作ったかを忘れてしまいました。数列 について覚えていることは以下の つです。
- である
- すべての に対し、 を満たす
- は負でない整数である
- を で割った余りは である
の組を定めると条件「2.」によって数列 がただ つ定まります。上の つの条件をすべて満たすような数列 は存在しますか?存在する場合は、数列 が辞書順最小になるようなものを求めてください。
なお、長さ の数列 が より辞書順で小さいとは、 つの列が異なって、 を であるような最小の正整数としたときに であることを言います。
長さ の数列の集合 のうち、 が辞書順最小とは、 が に含まれており、 に含まれる でない任意の数列 に対して は より辞書順で小さいことを言います。
制約
- は素数
- 入力はすべて整数
解法
数列 は線形方程式です。よって、 によらない定数 で、 を表されます。また、4. の条件によって、 は で割った余りのみを考えればよいです。
を で割った余りは、行列累乗と呼ばれるテクニックで時間計算量 で求められます。
その後は、 により、方程式 を満たす非負整数 のうち、辞書順最小のものを求める問題に帰着されます。ここで、 なら、 かつ である整数 がただ 1 つ存在します。 は の逆元と呼ばれており、 が素数の場合はフェルマーの小定理により であるので、 は時間計算量 で求められます。
なら、 を のうち となる最大のものとすると、 に対して
とすればこれが辞書順最小になっています。 のうち となるものが存在しない場合、 の左辺は でなく、右辺は常に であるので条件を満たす が存在せず、答えは No
です。
また、 なら、すべての に対して とすればよいです。
作者感想
この問題は二段階の考察に分かれ、知識も考察も実装も必要な問題でした。もともとは「 のうち、条件を満たす数列 の個数を で割った余りを求める」という問題がありましたが、最小辞書順を求める方が美しかったのでこっちを推しました。
問題は自分が思ったより解かれませんでしたが、Hard の難易度としてはなかなかバランスがよかったと思います。
Mex Max Matrix
作問者: @noya2
AC者数
ヒントなし | ヒント1 | ヒント2 | ヒント3 |
---|---|---|---|
3 | 0 | 1 | 0 |
問題文
長さ の非負整数列 および長さ の非負整数列 が与えられます。次のようにして定まる 行列 を考えます。
ただし、添字の は を、添字の は を動くものとします。
また、非負整数の有限集合 に対し は に含まれない最小の非負整数を表します。
個のクエリに答えてください。
番目のクエリでは が与えられるので、 を求めてください。
制約
- 入力はすべて整数
解法
の要素は高々 個であることがわかります。それらは であること、また、それらが現れる条件を丁寧に整理すると、クエリ毎に で答えを求めることができます。
作者感想
問題名の響きが良さそうなものを目指して作りました。かなりギャグです。
おわりに
特に問題やテストケースの不備もなくコンテストを終えることができました。しかし、CPCTF全体としてはPPC部門の問題の割合が大きすぎるという意見が寄せられました。来年以降は全体のバランスをCTF班の方々と協力して整えていこうと思います。
それでは、また来年のCPCTFでお会いしましょう!