AtCoder Beginner Contest 234のきろく
またまた日が空きました。AtCoder Beginner Contest 234に参加です。
- A - Weird Function (100点)
- B - Longest Segment (200点)
- C - Happy New Year! (300点)
- D - Prefix K-th Max (400点)
- E - Arithmetic Number (500点)
- F - Reordering (500点)
- G - Divide a Sequence (600点): 未提出
- Ex - Enumerate Pairs (600点、実行時間制限: 4 sec): 未提出
- 結果、感想
A - Weird Function (100点)
問題文にあるような関数を実装して、f(f(f(t)+t)+f(f(t)))
を出力させればいいです。
また、 であるため、こちらを実装するのもありでしょう。
多項式の計算にはHorner法を用いることで累乗による計算回数を減らすことができます。
B - Longest Segment (200点)
点の個数が と小さいため、全ての組 についての線分の長さ を計算して最大値を求めればいいです。
C++などの言語ではstd::fixed
, std::setprecision
や"%.8d"
などを用います。
C - Happy New Year! (300点)
を に変換してもその大小関係は変わらないため、条件を満たす中で 番目に小さい数は二進数表記での に対応します。そのため十進数を二進数に変換し、 を に変換することで答えが求まります。
D - Prefix K-th Max (400点)
毎回、既出の数のリストから 番目に大きな数を求めたり、ソートしたりすると計算量が や となってしまい、TLEします。
ある時点で大きい方から 番目以降の数がそれ以降で答えになることはないため、各時点での大きい方から 番目までの数が分かればいいです。よってこれらを集合std::set
や優先度付きキューstd::priority_queue
を用いて、毎回、この集合内の最小値と の比較で大きい方を集合内にあるようにして要素数が常に になるようにすれば、その中の最小値が各回の答えになり、全体として になります。
コンテスト内では最初は、二重二分探索で 解で通しましたが、探索範囲を間違えて2WA出してしまいました。
E - Arithmetic Number (500点)
一番左の数は から の 通り、公差は から の 通りであるため、これらを全探索することができます。各条件について右に数を増やしていき(増やす数がマイナスになればその条件については打切り)、 以上になったら、答えの候補にして、その中の最小値が答えとなります。
F - Reordering (500点)
内の 種目の英小文字の出現数を とします。このとき
というDPを考えます。公式解説では貰うDPで考えているようでしたが、私は配るDPをもとに考えました。の状態について 種目の英小文字を文字の隙間(前後含む) 個の隙間に配置していきます。このとき同じ隙間に複数個おいてもよく、1個も置かれない隙間があってもいいです。初期状態として について に を足すことで答えが と求まります。ここで は重複組み合わせで であり、変形すると公式解説と同じとなります。
G - Divide a Sequence (600点): 未提出
これもDPっぽいですが、未だ解けてません。
Ex - Enumerate Pairs (600点、実行時間制限: 4 sec): 未提出
計算量が落ちない...
結果、感想
ちゃんと6完で来たので良かったという感じですが、Dで2WA出してしまったのが痛いなと、要反省です。
エクサウィザーズプログラミングコンテスト2021(AtCoder Beginner Contest 222)のきろく
エクサウィザーズプログラミングコンテスト2021(AtCoder Beginner Contest 222)参加!
- A - Four Digits (100点)
- B - Failing Grade (200点)
- C - Swiss-System Tournament (300点)
- D - Between Two Arrays (400点)
- E - Red and Blue Tree (500点)
- F - Expensive Expense (500点、実行時間制限: 4 sec)
- G - 222 (600点): 未提出
- H - Beautiful Binary Tree (600点、実行時間制限: 3 sec): 未提出
- 結果、感想
A - Four Digits (100点)
以下なら先頭に0
を追加して...という風にもできますが、やることはゼロ埋め4桁出力なので、printf
やマニピュレータによるフォーマット出力で対応できます。
printf("%04d\n", N);
cout << setw(4) << setfill('0') << N << endl;
B - Failing Grade (200点)
for
文を用いて各 について であるかを調べればいいです。
C - Swiss-System Tournament (300点)
各回毎に前の順位から今回の順位を求まられればいいです。
前回の順位で、上位からどのプレイヤーかが分かれば各試合する組み合わせが分かるので、各プレイヤーがその時点で何勝しているかが分かるので、それを勝数毎のバケツに入れて、各勝数について大きい順に、中のプレイヤーをインデックスの小さい順に取ってやれば、その試合の後の順位が上位から順に求まります。
D - Between Two Arrays (400点)
次のようなDPがまず思いつきます。
として、において についてという遷移で答えが (範囲は で十分) と求まりますが、このままでは として計算量が となってしまうので間に合いません。ここで の部分について累積和を利用することで にでき、これでACをとることができます。
また、 として遷移式を のときにも適応させることで場合分けや初期化を減らすこともできます。
E - Red and Blue Tree (500点)
各辺を通る回数の配列 が求まれば、 として部分和を とするような要素の選び方の数としてDPなどで求まります。
このときのDPは
として、 において についてという遷移で答えを で求めることができます。を求めるのは、DFS等で で求めることができるので、全体として で答えが求まりました。
F - Expensive Expense (500点、実行時間制限: 4 sec)
制約より与えられたグラフは木であることが分かります。全方位木DPで答えは求まるそうですが、私は書けないです。ここでコンテスト終了後に直径を利用する解き方でACしました。
もともとの木に頂点 と の各 について頂点 と を結ぶコスト の辺を追加します。この追加後も木の儘です。頂点 間の距離を と書きます。また、 とします。
ここで頂点の組 が直径をなす、即ち であるように取ります。このとき任意の頂点 について が成立します。
先ずはこれを証明します。
となるような頂点の組 が存在すると仮定します。このとき、 も も や でないことは自明です。また、 のパス上で から最も近い点を とすると となります。
- と の2つのパスが交わらない場合:
より が直径であることに反します。
- と の2つのパスが交わる場合:
のうち、 に近い方が であるように仮定します(そうでない場合は を入れ替える)。このとき となりこちらでも が直径であることに反します。
よってこの二つより、背理法により示したことが示されました。
ここまで来れれば、double-sweep等によって を求め、 の各 について を求めればよいと思ってしまいますが、最初の街では観光しないので、例えば のときは ではなく が答えとなります。
この解き方では4つの始点について最短距離を求めるので や で求めることができます。
G - 222 (600点): 未提出
数式こねくり回したら出来そう
H - Beautiful Binary Tree (600点、実行時間制限: 3 sec): 未提出
難しそう
結果、感想
ちゃっと増加してよかったなっていう感じですが、時間内にFも通したかったなと、ちゃんと精進しないといけないねと思わされました。
AtCoder Beginner Contest 221のきろく
久しぶりの更新です。AtCoder Beginner Contest 221に参加です。
- A - Seismic magnitude scales (100点)
- B - typo (200点)
- C - Select Mul (300点)
- D - Online games (400点)
- E - LEQ (500点)
- F - Diameter set (500点)
- G - Jumping sequence (600点、実行時間制限: 5 sec): 未提出
- H - Count Multiset (600点): 未提出
- 結果、感想
A - Seismic magnitude scales (100点)
答えは となります。pow
などを用いてもこの問題ではOKですが、場合によっては誤差が発生しうるのでfor
文を使うのが無難と思いそちらで組みました。
B - typo (200点)
問題文の通り、何も操作を行わないとき、 文字目と 文字目を入れ替えたとき、それぞれについて一致するかどうかを調べることで解けます。
実装的には各 について 文字目と 文字目を入れ替えたときと戻した時を判定すれば、何も操作を行わないときについて別個に書く必要がなくなるので、コードは短くなりますね。
C - Select Mul (300点)
の各桁の数字を任意の順番に並べて、その先頭の数と、後ろの数と見做すことで全ての分離方法を考えることができ、その方法は の桁数を とするとき 通りあり、計算量も となります。
ここで、各分離方法について、それぞれの数字を降順にソートした方が答えが大きくなるため、各数字を2つのグループのどちらかに所属するかの 通りのみの分離方法のみ調べる必要性があることになります。これはbit全探索を用いて計算量 で実装できます。
本番では後者の方法がすぐ思い浮かんだので、そちらでのみ実装しました。
どうやら 解 や 解があるようですが、こんなの本番中に思いつけへんやん...
D - Online games (400点)
全ての日について考えると最大で 日目まで考える必要があるので、間に合いません。人数の変動があるのは各 について 日目と 日目なので、その節目で人数が何人になって、その間隔が何日なのかを計算することで答えを求めることができます。
本番では間隔の前後を間違えて1WAしました。
E - LEQ (500点)
が , が であるような部分列の個数は のそれぞれを選ぶかどうかの 通りであるため、求める答えは です。
であるため として を選んだ時、 となるような について を足していき、 で割ることでこのときの部分列数が求まります。よってこれを全ての について足していけばいいことができます。
これは について という重みを付けた個数のセグ木について添え字の降順に走査することで実装することができますが、 の値が 程度になることにもなるため座標圧縮してやる必要があります。
本番ではセグ木の演算でmodをとらせるということをしていなかったため1WA出してしまいました。
F - Diameter set (500点)
木の直径はdouble sweep によって求めることができます。そこから木の中心 を求めますが、この時、直径の偶奇で場合分けをしますが、各辺上に頂点を追加してやることで、直径を2倍にし、偶数にすることができ、この直径を とします。
この木を を根とする根附き木として、 の直接の子を として、 以外の点をそれぞれどの の子孫(または 自身)であるかでグループ分けします。各グループについて からの距離が であるような点の個数を とします。条件を満たす点の選び方は各グループについて距離 の点を高々1つづつ選んでいき、かつ選んだ個数が 以上のものであるため、 通りとなります。
本番ではグループを高々2つまでしか考えてなくて爆死しました。
G - Jumping sequence (600点、実行時間制限: 5 sec): 未提出
何かしら圧縮してDPなんやろうなぁと思ってます。
H - Count Multiset (600点): 未提出
DPなのかな
結果、感想
8問ABCになってから調子悪かったのですが、久しぶりに良いパフォが取れました。このまま1700まで恢復していきたいですね。
Codeforces Round #737 (Div. 2)のきろく
久しぶりのCodeforces&参戦録です。レート冷えなくてなんとか安心したっていう感じです。問題文和訳はこちら
- A. Ezzat and Two Subsequences / Ezzat и две подпоследовательности (500点)
- B. Moamen and k-subarrays / Moamen и k-подотрезки (1000点)
- C. Moamen and XOR / Moamen и XOR (1750点)
- Ezzat and Grid / Ezzat и таблица (2500点): 未提出
- E. Assiut Chess / Шахматы в Assiut (3000点): 未提出
- 結果、感想
A. Ezzat and Two Subsequences / Ezzat и две подпоследовательности (500点)
最大値の影響を大きく、最小値の影響を小さくしたいので、最大値を少ない方の部分列に、最小値を多い方の部分列にもっていければいいかなと思いました。公式解説によると、最大値とそれ以外で分ければいいようですが、本番は証明できず、少し怖かったので配列をソートして、 として、 を出力することにしました。
B. Moamen and k-subarrays / Moamen и k-подотрезки (1000点)
でソートできる場合、 では要素数が 以上の連続部分列を分割すれば、同様にソートすることができるので、ソートできる最小分割数を求めればいいことが分かります。
についてソート後においても連続する みたいな感じ ときは同一連続部分列に属すようにしてもいいですが、そうでない場合は違う連続部分列に属すようにしなければなりません。よって連続部分列の最小数は、ソート後においても連続するような部分列の数となります。
C. Moamen and XOR / Moamen и XOR (1750点)
桁DPです。
とすると、です。各桁について数字の選び方は 通りです。上位桁で左辺の方が大きいことが決まっている場合、下位については任意の選び方で左辺の方が大きくなります。
が奇数のときは、bitAND が となる、全てが のときはbitXORも であり、bitANDもbitXORも となるのは偶数個のみが であるときで、 通りであるので
となります。が奇数のときは、bitAND が となる、全てが のときはbitXORは であり、bitANDもbitXORも となるのは偶数個のみが であるときで、 通りであるのでとなります。
Ezzat and Grid / Ezzat и таблица (2500点): 未提出
分かりません...
E. Assiut Chess / Шахматы в Assiut (3000点): 未提出
コンテスト中には、問題文すら見ていませんでした...
結果、感想
久しぶりの参戦でレートを温めることができて嬉しいです。このまま紫になりたいなぁ。
Codeforces Round #737 (Div. 2) 問題文和訳
- A. Ezzat and Two Subsequences / Ezzat и две подпоследовательности (500点)
- B. Moamen and k-subarrays / Moamen и k-подотрезки (1000点)
- C. Moamen and XOR / Moamen и XOR (1750点)
- D. Ezzat and Grid / Ezzat и таблица (2500点)
- E. Assiut Chess / Шахматы в Assiut (3000点)
A. Ezzat and Two Subsequences / Ezzat и две подпоследовательности (500点)
テストごとのメモリ制限: 256 MB
入力: 標準入力
出力: 標準出力
数列 からいくつか(0個や全ての場合もあり)を削除することで数列 が得られるとき、 は の部分列であるといいます。
部分列の平均とは、この部分列の数値の合計を部分列の大きさで割ったものです。
例えば、 の平均は であるため、 となります。
入力
1行目には単一の整数 が与えられる、これはテストケース数である。各テストケースは2行から成る。
各テストケースの1行目には単一の整数 が与えられる。
2行目には 個の整数 が与えられる。
全てのテストケースでの の和が を超えないことは保証されている。
出力
各テストケースについて、単一の値を出力せよ、その値とはEzzatが達成できる最大値である。
絶対誤差または相対誤差が を越えなければ正解と見做される。
形式的には、提出解を 、ジャッジ解を とする。 であるとき、正答とみなされる。
入出力例
4 3 3 1 2 3 -7 -6 -6 3 2 2 2 4 17 3 5 -3
4.500000000 -12.500000000 4.000000000 18.666666667
注記
1つ目のテストケースでは、配列は です。この配列を分割する全ての方法は次のようなものです。
- 。このとき値は となる
- 。このとき値は となる
- 。このとき値は となる
従って、可能な最大値は となります。
2つ目のテストケースでは、配列は です。この配列を分割する全ての方法は次のようなものです。
- 。このとき値は となる
- 。このとき値は となる
従って、可能な最大値は となります。
B. Moamen and k-subarrays / Moamen и k-подотрезки (1000点)
テストごとのメモリ制限: 256 MB
入力: 標準入力
出力: 標準出力
- 各要素が正確に1つの連続部分列に属すように、配列をちょうど 個の空でない連続部分列に分割する
- これらの部分配列を任意に並び替える
- 新しい順序で部分配列を結合する
数列 の先頭からいくつか(0個や全ての場合もあり)の要素を削除し、末尾からいくつか(0個や全ての場合もあり)の要素を削除することで数列 が得られるとき、 は の連続部分列であるといいます。
上記の操作を正確に一度だけ行って、配列を非減少順に並び替える方法があるかどうか、Moamenに教えてください。
入力
1行目には単一の整数 が与えられる、これはテストケース数である。テストケースについての記述が続く。
各テストケースの1行目には2つの整数 が与えられる。
2行目には 個の整数 が与えられる。全ての数が相異なることは保証されている。
全てのテストケースでの の和が を超えないことは保証されている。
出力
各テストケースについて、単一の文字列を出力せよ。
Moamenが配列を非減少順に並び替えることができる場合、"YES
"(引用符なし)と出力せよ。そうでなければ、"NO
"(引用符なし)と出力せよ。
"YES
"と"NO
"の各文字はどの活字ケース(大文字/小文字)で出力してもよい。
入出力例
3 5 4 6 3 4 2 1 4 2 1 -4 0 -2 5 1 1 2 3 4 5
Yes No Yes
注記
1つ目のテストケースでは、 であり、次のように操作を行うことができます。
- を に分割する
- 並び替える:
- 結合する: これで配列はソートされた
2つ目のテストケースでは、配列を つの連続部分列に分割してソートを行う方法はありません。
例えば、配列を に分割した場合、 または のようにしか並び替えることができません。しかし、どちらの場合も、結合後の配列はソートされていません。
C. Moamen and XOR / Moamen и XOR (1750点)
テストごとのメモリ制限: 256 MB
入力: 標準入力
出力: 標準出力
である場合、Moamenが勝ちます。
ここで はbit単位AND*3を、 はbit単位XOR*4を表します。
Moamenが勝つような配列 の個数を計算してください。
結果は非常に大きくなる可能性があるため、 で割った値を出力してください。
入力
1行目には単一の整数 が与えられる、これはテストケース数である。
各テストケースは2つの整数 を含む1行で構成される。
出力
各テストケースについて、単一の値を出力せよ、その値はMoamenが勝つような配列の個数である。
結果を modulo で出力せよ。
入出力例
3 3 1 2 1 4 0
5 2 1
注記
1つ目のテストケースでは、 です。結果として、可能な配列は で全てです。
Moamenはそのうち5つでのみ勝利します: 。
D. Ezzat and Grid / Ezzat и таблица (2500点)
テストごとのメモリ制限: 256 MB
入力: 標準入力
出力: 標準出力
グリッドの全ての連続する2行について、この2行に を持つような列が少なくとも1つ存在する場合、かつその場合のみグリッドは美しいといいます。
Ezzatは行数 と、数字 を含むグリッドの 個のセグメントを与えます。 各セグメントは3つの整数 で表され、 は行番号を、 はその行のセグメントの最初と最後の列を表します。
例えば、 で、セグメントが であるとき、グリッドは次のようになります。
グリッドを美しくするために削除しなければならない最小の行数をEzzatに伝えてください。
入力
1行目には2つの整数 が与えられる。
続く 行のそれぞれには3つの整数 が与えられる。これら 行のそれぞれは行番号 は 列目から 列目(両端含む)までに数字 を含んでいることを表す。
セグメントは重なることもあることに注意せよ。
出力
1行目には単一の整数 を出力せよ、これは削除しなければならない最小の行数である。
2行目には削除しなければならない行を表す 個の相異なる整数 をいずれかの順序で出力せよ。
解が複数ある場合は、そのいずれかを出力せよ。
入出力例
3 6 1 1 1 1 7 8 2 7 7 2 15 15 3 1 1 3 15 15
0
5 4 1 2 3 2 4 6 3 3 5 5 1 1
3 2 4 5
注記
1つ目のテストケースのグリッドは問題文で説明されているものです。このグリッドは次のような特性を持っています。
- 行目と 行目は列 に共通して を持つ
- 行目と 行目は列 に共通して を持つ
結果として、このグリッドは美しく、どの行も削除する必要はありません。
2つ目のテストケースでは、グリッドは次のようになります。
E. Assiut Chess / Шахматы в Assiut (3000点)
テストごとのメモリ制限: 256 MB
入力: 標準入力
出力: 標準出力
ICPC Assuit(أسيوط)*5 コミュニティ(以下、ICPC Assiut Community)がユニークなチェスの大会を開催することとなり、貴方はクイーンを操って隠れたキングを追い詰める役に選ばれました。キングはICPC Assiut Communityのメンバーがキングを操ります。
のチェス盤上で対戦を行い、行は上から下へ、列は左から右へと数字が振られていて、 行 列にあるマスは と表されます。
1手でクイーンを同一横線上、縦線上、斜線上のいずれかのマスに移動させることができます。例えば、クイーンが にあった場合、 *6 のいずれかに移動できます。クイーンは現在のマスに留まることはできないことに注意してください。
1手でキングは盤面から出ないように「右」「左」「上」「下」「右下」「左下」「左上」「右上」のいずれかに移動できます。キングはクイーンと同じ行、列、斜線上にあるマス(クイーン自身がいるマスを含む)に移動することはできません。例えば、キングがマス にいた場合、 に移動することができます。
ゲーム開始時に、クイーンを盤上の任意のマスに配置し、これはゲーム注意回のみ行われます。その後、クイーンとは異なる位置にキングが秘かに置かれます。貴方にはキングの位置は分かりません。その後、キングを先手として、キングとクイーンが交互に手を打ちます。キングは可能な方向(「右」「下」「上-左」など)に動き、その方向のみが貴方に伝えられます。そののち、クイーンが移動するマスを宣言し、クインを移動させなければなりません。このようにしてゲームは、貴方が勝つか、手番がなくなるまで続きます。
キングに有効な手がなくなれば貴方の勝ちです。 回クイーンを動かした後もキングに有効な手があれば、貴方の負けです。
入力
1行目には単一の整数 が与えられる、これはテストケース数である。
相互入出力
各テストケースにおいて、クイーンの開始位置を直ちに出力せよ。キングのいるマスにクイーンを置いた場合、直ちに勝利する。
その後、最大で 手を打つことができる。各手は という形式で行われる、ここで はそれぞれクイーンの亜tらしい行と列を表す2つの整数である。この手はクイーンの有効な手でなければならない。
最初のクイーンの配置の後や自分の手の後、キングの移動方向を表す文字列 を受け取る。これは次のうちのいずれかである: "Right
", "Left
", "Up
", "Down
", "Down-Right
", "Down-Left
", "Up-Left
", "Up-Right
"、もしくは勝利時の"Done
"。"Done
"は各テストケースの終わりとして考えよ。
クエリを出力した後、忘れず改行を出力し、出力をflushせよ。そうでなければIdleness limit exceededを得る。出力のflushのためには、次を利用せよ。
- C++の場合、
fflush(stdout)
やcout.flush()
- Javaの場合、
System.out.flush()
- Pascalの場合、
flush(output)
- Pythonの場合、
stdout.flush()
- 他の言語の場合は、ドキュメントを参照せよ
無効なクエリを出力したり、各テストケースで 個を超えるクエリを出力しようとした場合、ゲームは直ちに終了し、Wrong Answer判定となる。
入出力例
1 Left Right Done
7 5 7 6 7 7
注記
この入出力例では、開始時に隠れキングは にいました。ゲームは次のように続きます。
AtCoder Beginner Contest 204のきろく
AtCoder Beginner Contest 204で久しぶりにレート上昇しました!
- A - Rock-paper-scissors (100点)
- B - Nuts (200点)
- C - Tour (300点)
- D - Cooking (400点)
- E - Rush Hour 2 (500点)
- F - Hanjo 2 (600点): 未提出
- 結果、感想
A - Rock-paper-scissors (100点)
人のじゃんけんであいこになるのは、全員同じ手を出すか、全員違う手を出した時なので、 のときはその手、そうでないときは の手を出せばいいです。また、サーバルの出した手に対応する文字を としたとき、 となることを利用すると となります。
B - Nuts (200点)
for
とif
を組み合わせて答えを出すことができますが、各 について足す数は であるのでこれを足していく方が多分少し短いです。
C - Tour (300点)
全頂点対について移動が可能かどうかなので、Warshall-Floyd法で...とすると なので間に合いません。
始点を固定した時同じ頂点を2度以上訪れないようにしたDFSやBFSを行うと、どの頂点も辺も高々1回しか通らないので でその始点から訪れることができるかどうか判別できるので、その始点を全て試して足して合わせてやることで で判定することができます。
D - Cooking (400点)
コストをlong long
にし忘れと辺を双方向につなぎ忘れによって3WA出してしまいました... これがなければ、青色復帰できたのに...
を二つの集合 に空集合を許した分割を行ったときの が答えです。分割の方法は 通り存在するため、全探索では間に合いません。
この問題は部分和問題であるためDPの利用を考えます。
E - Rush Hour 2 (500点)
任意の整数時間待機することができるので、各都市への最速到達時間を考えればいいです。道路 を通って都市 から時刻 に出発して都市 に到達する時刻は となります。 とした時 であり、 は で単調減少、 で単調増加することから、 のときに最小値をとり、 であることから も 附近で最小値をとることが分かります。ちゃんとした解説は公式解説を参照して下さい。
上記から各道を通った時の反対側に着く時刻が最小値となるような出発時刻 が求まります。よって、頂点 に到達可能な最速時刻が であるとき、 の時は まで待ってから、 の時は即座に道 を用いることでその道を用いて へ行く経路のうち最速で に行くことができるため、このように改造したDijkstra法で答えを求めることができます。
F - Hanjo 2 (600点): 未提出
制約からbitDP+行列累乗かなと思いましたが、漸化式が書けませんでした...
結果、感想
久しぶりにレートが上昇しました。速く青色復帰したいです。
ZONeエナジー プログラミングコンテスト “HELLO SPACE”のきろく
ZONeエナジー プログラミングコンテスト “HELLO SPACE”に参加、レートを大幅に冷やしてしまいました...
- A - UFO襲来 / UFO Invasion (100点)
- B - 友好の印 / Sign of Friendship (200点)
- D - 宇宙人からのメッセージ / Message from Aliens (300点)
- C - MAD TEAM (400点)
- E - 潜入 / Sneaking (500点)
- F - 出会いと別れ / Encounter and Farewell (600点): 未提出
- 結果、感想
A - UFO襲来 / UFO Invasion (100点)
長さは 文字なので愚直に書くこともできますがfor文を用いてi
文字目から4文字の部分文字列がZONe
であるかどうかを判別すればいいです。
B - 友好の印 / Sign of Friendship (200点)
距離 高さ の遮蔽物が邪魔にならないのはUFOと遮蔽物の上端を結ぶ直線とタワーの交点以上上った時であり、その高さを とすると三角形の相似より 依り であるため答えは となります。
D - 宇宙人からのメッセージ / Message from Aliens (300点)
実際に文字列を反転させるのは文字列長ほどの計算量を要するので時間がかかります。反転しているかどうかbool
型の変数を用意しておき、その状態に合わせて前後から文字を追加できるようにdeque
を利用します。
後半の同じ文字を取り除くのは文字を1文字ずつ取り出していくとき、答えの文字列の末尾と追加する文字が同じときに取り除き、そうでないときそのまま追加するとすることによって実現することができます。
C - MAD TEAM (400点)
最小値の最大化なので二分探索であることは思いつきましたがそれに必要な判定方法をコンテスト中に思いつくことができませんでした。
答えが 以上かどうかを考える時各人の各能力が 以上かどうかしか考える必要がなく、5 bitの数と考え、状態を圧縮し、3人を選んだ時に全てがtrueになるかどうかを判定すればいいことが分かります。3人を選ぶときは各人の5 bitの数を集合などに入れてやることで高々 種類しか考える必要がなくなり、そこから重複を許して3つ選んでやることでOKかどうか分かります。
E - 潜入 / Sneaking (500点)
愚直に辺を張ると辺の本数が となり、Dijkstra法でも間に合わないなと考えていました。 何かこれでも通る人は通るみたいですね...通しとけばよかった
軸の負方向への移動は がなければ隣の頂点へのコスト の辺で表すことができます。そこで頂点を2階層とし、 軸の負方向への移動だけは2階層目で、その他は1階層で行うことにします。1階層から2階層の対応する頂点へはコスト その逆はコスト とすることで、問題文の移動を 本の辺で表現することができ、Dijkstra法で十分間に合う本数になります。
F - 出会いと別れ / Encounter and Farewell (600点): 未提出
線形の基底らしいですね、履修しておきます...
結果、感想
CやEが解けず、レートを冷やしてしまいました... 2週間連続で冷やしているので、何とか挽回していきたきですね。