AtCoder Beginner Contest 241(Sponsored by Panasonic)のきろく
AtCoder Beginner Contest 241(Sponsored by Panasonic)に参加。
- A - Digit Machine (100点)
- B - Pasta (200点)
- C - Connect 6 (300点、実行時間制限: 3 sec)
- D - Sequence Query (400点)
- E - Putting Candies (500点)
- F - Skate (500点)
- G - Round Robin (600点)
- Ex - Card Deck Score (600点、実行時間制限: 3 sec): 未提出
- 結果、感想
A - Digit Machine (100点)
が答えです。
見にくいので別表記すると として となります。
B - Pasta (200点)
std::map
で各長さの麵の本数を管理すると楽。
C - Connect 6 (300点、実行時間制限: 3 sec)
マス以上が黒であるような連続 マスが存在するとき、答えはYes
、そうでないときNo
となります。
連続 マスは各マスから8方向へ6回探索すればよく、それぞれについて黒マスの数を数えればいいです。
尚、全てのマスについて調べるので8マスのうち半分は調べなくてもいいです((上, 下), (左, 右), (左上, 右下), (右上, 左下)の各組について片方のみでよい)。
斜めについて マスに達してないのにYes
にしてしまうというミスで4WAしました...
D - Sequence Query (400点)
は高々 であるので、std::multiset
やstd::map
で管理したとき、イテレータの移動が高々 回なので、間に合います。
前にbegin()
を超えるかよりも後ろにend()
を超えるかを判定する方が楽だったりするので、 のクエリについては全体に を掛けたもので行うと少し楽になるかも(人に依る?)。
std::multiset
でbegin()
やend()
を超えて操作を行ってしまったコードを出してしまい、1TLEしてしまいました...
E - Putting Candies (500点)
ダブリングを行います。
とします。このとき で割った時の商と余りに注目することで となるので、 を二進数で表した時、 である桁を下から とした時、最初 として を から へ順にを繰り返して、最終的な が答えとなります。本番では各DPの値は (商, 余り) の組として実装しました。
F - Skate (500点)
も も最大で まで取りえるので、全てのマスについて調べることはできません。しかし、途中で立ち寄ることができるマスは障害物の上下左右いずれかの隣接マスのみなのでスタート地点を入れても高々 箇所です。そのため、これらの限定した頂点についてのBFSで答えを求めることができます。
ぶつかる障害物についてはstd::map<int, std:::vector>
での二分探索によって求めることができます。
G - Round Robin (600点)
終了後に解説ACしました。
この解説のとおりに実装しました。
試合からプレイヤーへの辺のうち一方にしか流せないようにすることで一方のみが勝つという状況を表せるのがすごいと思いました。
ちゃんとフローについて勉強しなきゃ...
Ex - Card Deck Score (600点、実行時間制限: 3 sec): 未提出
多項式.... 分かんね...
結果、感想
1700附近まで回復させることができました。でもCの4WAで焦ってしまったのは要反省だなと思いました。
Educational Codeforces Round 123のきろく
問題文和訳はこちら
- A. Doors and Keys / Двери и ключи
- B. Anti-Fibonacci Permutation / Антифибоначчиевы перестановки
- C. Increase Subarray Sums / Увеличь суммы подотрезков
- D. Cross Coloring / Раскраска крестиками
- E. Expand the Path / Расширь маршрут: 未提出
- F. Basis / Базис (実行時間制限: 6 sec): 未提出
- 結果、感想
A. Doors and Keys / Двери и ключи
R
, G
, B
の各文字について大文字よりも前に小文字があるかを調べます。find
関数を用いたり、配列で既出かどうかを記憶するなどの方法があります。
B. Anti-Fibonacci Permutation / Антифибоначчиевы перестановки
降順順列 は条件を満たします。また、この順列の連続する2要素を入れ替えたものも条件を満たすので、これで 通りの順列を作ることができました。
C. Increase Subarray Sums / Увеличь суммы подотрезков
であるので であっても大丈夫なので、初期状態での全ての部分列の和を計算することができるので、長さ毎にその最大値を記憶します。長さ のものを とします。
この時 となるのでそれぞれ計算することができます。
D. Cross Coloring / Раскраска крестиками
最終的な盤面において各セルのについて何番目の操作で着色されたのかが分かれば、最終的な彩色に関わる操作が 個存在するとき答えは となります。
番目の操作は、それ以降に行 と列 の両方が塗り替えられる、もしくは全ての行か全ての列が塗り替えられる、のいずれかを満たした時、最終的な彩色に関わず、そうでないとき、関わります。そのため、最後の操作から逆順にどの行や列が操作されたかを記憶しておくことで答えを出せます。しかし、「全てのテストケースでの の和は を超えない」という制約はありますが、 についてはそうでないため、その和は にまでなる可能性があるので、配列で管理するとTLEとなります。そのため、出てきた行や列をstd::set
やstd::unordered_set
で管理して計算量を落とす必要があります。(これに気附かず、何度もペナルティを食らいました...)
E. Expand the Path / Расширь маршрут: 未提出
分かりそうで分からない...
F. Basis / Базис (実行時間制限: 6 sec): 未提出
さっぱりですね。
結果、感想
レートが上がりましたが、Dのペナルティ酷いなぁ... ちゃんと条件を読むようにしないと...
Educational Codeforces Round 123 問題文和訳
- A. Doors and Keys / Двери и ключи
- B. Anti-Fibonacci Permutation / Антифибоначчиевы перестановки
- C. Increase Subarray Sums / Увеличь суммы подотрезков
- D. Cross Coloring / Раскраска крестиками
- E. Expand the Path / Расширь маршрут
- F. Basis / Базис
A. Doors and Keys / Двери и ключи
テストごとのメモリ制限: 256 MB
入力: 標準入力
出力: 標準出力
廊下には、赤、緑、青の扉の3つの扉があります。扉は順々に並んでいますが、順番は違うものかもしれません。次の扉に進むためには、騎士はまず、先の扉を開かなければなりません。
それぞれの扉は、対応する色の鍵でのみ開けることができます。赤、緑、青の鍵の3つの鍵も廊下のどこかに置かれています。扉を開けるためには、騎士はまず、その色の鍵を拾う必要があります。
騎士は廊下の地図を所持しています。その地図は、6文字から成る文字列として記述することができます。
R
,G
,B
: それぞれ赤、緑、青の扉を表すr
,g
,b
: それぞれ赤、緑、青の鍵を表す
この6文字はそれぞれちょうど1度ずつだけ文字列の中に現れます。
騎士は通路の前、即ち地図の左側に立っています。
廊下の地図が与えられたとき、騎士が全ての扉を開けて廊下の先にいる姫に会うことができるかどうかを判定して下さい。
入力
1行目には単一の整数 が与えられる、これはテストケースの個数である。
各テストケースは単一の文字列から成る。各文字はR
, G
, B
(扉)、r
, g
, b
(鍵)のいずれかで、それぞれちょうど一回ずつ現れる。
出力
各テストケースについて、騎士が全ての扉を開けることができる場合、YES
を出力せよ。そうでない場合、NO
を出力せよ。
入出力例
4 rgbBRG RgbrBG bBrRgG rgRGBb
YES NO YES NO
注記
1つ目のテストケースでは、騎士はまず全ての鍵を集め、そしてその鍵で全ての扉を開けます。
2つ目のテストケースでは、騎士の目の前に赤い扉がありますが、騎士はその扉用の鍵を持っていません。
3つ目のテストケースでは、それぞれの扉の前に鍵があるので、騎士は鍵を集めてすぐに使用することを3回行います。
4つ目のテストケースでは、騎士は青い扉を開けることができません。
B. Anti-Fibonacci Permutation / Антифибоначчиевы перестановки
テストごとのメモリ制限: 256 MB
入力: 標準入力
出力: 標準出力
与えられた数 に対して、長さ の相異なるanti-Fibonacci順列を出力して下さい。
入力
1行目には単一の整数 が与えられる、これはテストケースの個数である。
各テストケースの単一行には、単一の整数 が与えられる。
出力
各テストケースについて 行出力せよ。各行には長さ のanti-Fibonacci順列が含まれていなければならない。各テストケースにおいて、各順列を2回以上出力してはいけない。
答えが複数存在する場合、そのうちのいずれかを出力せよ。この問題の制約の下では,長さ の相異なるanti-Fibonacci順列を得ることが常に可能であることは証明できる。
入出力例
2 4 3
4 1 3 2 1 2 4 3 3 4 1 2 2 4 1 3 3 2 1 1 3 2 3 1 2
C. Increase Subarray Sums / Увеличь суммы подотрезков
テストごとのメモリ制限: 256 MB
入力: 標準入力
出力: 標準出力
を、次の操作を行った後の の連続部分列の最大和とします: ちょうど 個の異なる位置の要素に を加える。空部分列も考慮し、その和は です。
部分列は、増加した要素全てを含む必要はないことに注意してください。
から までの全ての について、 の最大値を独立に計算してください。
入力
1行目には単一の整数 が与えられる、これはテストケースの個数である。
テストケースの1行目には2個の整数 が与えられる、これらは配列の大きさと加算値である。
2行目には 個の整数 が与えられる。
全てのテストケースでの の和は を超えない。
出力
各テストケースについて 個の整数を出力せよ、それらはそれぞれ から までの全ての についての の最大値である。
入出力例
3 4 2 4 1 3 2 3 5 -2 -7 -1 10 2 -6 -1 -2 4 -6 -1 -4 4 -5 -4
10 12 14 16 18 0 4 4 5 4 6 6 7 7 7 7 8 8 8 8
注記
1つ目のテストケースでは、どの要素に を足すかは関係ありません。和が最大となる部分列は常に配列全体です。 個の要素を だけ増やすと、 が和に足されます。
2つ目のテストケースでは、
- では、空部分列が最適である。
- では、位置 の要素を増やすのが最適である。最適和は部分列 *1 の となる。
- では、位置 と他の1つの位置の要素を増やすのが最適である。最適和は部分列 の のままである。
- では、全ての要素を増やさなければならない。最適和は部分列 の となる。
D. Cross Coloring / Раскраска крестиками
テストごとのメモリ制限: 256 MB
入力: 標準入力
出力: 標準出力
このシートに対して 回操作を行いました。そのうちの 番目の操作は次のように表されます。
- : 白でない 色のうち1色を選び、行 全体と列 全体をその色で塗る。操作の前に着色されていたかどうかに関係なく、各セルに新しい色が適用される。
回の操作を全て適用した後のシートを彩色と呼びます。異なる色に着色されたセルが少なくとも一つ存在したとき、2つの彩色は異なるといいます。
彩色は何通り存在しますか? 数をmodulo で出力して下さい。
入力
1行目には単一の整数 が与えられる、これはテストケースの個数である。
テストケースの1行目には4個の整数 が与えられる、これらはシートの大きさ、白以外の色数、操作回数である。
続く 行の 行目には 番目の操作についての記述が与えられる。2個の整数 で、それぞれ操作を適応する行と列である。
全てのテストケースでの の和は を超えない。
出力
各テストケースについて単一の整数を出力せよ、その数とは彩色数のmodulo である。
入出力例
2 1 1 3 2 1 1 1 1 2 2 2 3 2 1 1 1 2 2
3 4
E. Expand the Path / Расширь маршрут
テストごとのメモリ制限: 256 MB
入力: 標準入力
出力: 標準出力
ロボットがセル に配置されています。ロボットは次の2種類の移動を行うことができます。
D
: 下に1セル移動R
: 右に1セル移動
ロボットはグリッドの外に出ることはできません。
一連の動き が与えられます、これはロボットの初期経路です。この経路でロボットがグリッドの外に進むことはありません。
これに対して、任意回数修正を加えることができます(0個の場合も可)。1回の修正では、一連の中の動きの1つを複製することができます。即ち、D
をDD
に、R
をRR
に置き換えます。
そのセルを通り、グリッドの外に進むことのないような修正後の経路が存在するようなセルの個数を数えて下さい。
入力
1行目には単一の整数 が与えられる、これはテストケースの個数である。
各テストケースの1行目には単一の整数 が与えられる、これはグリッドの行や列の数である。
各テストケースの2行目には文字D
とR
のみから成る、空でない文字列 が与えられる、これは初期経路である。この経路でロボットがグリッドの外に進むことはない。
全てのテストケースでの文字列 の長さの和は を超えない。
出力
各テストケースについて単一の整数を出力せよ、その数とは、そのセルを通り、グリッドの外に進むことのないような修正後の経路が存在するようなセルの個数である。
入出力例
3 4 RD 5 DRDRDRDR 3 D
13 9 3
注記
1つ目のテストケースでは、次のような修正経路を考えれば十分です。
RD
RRD
RRRD
RRRDD
RRRDDD
: この経路ではセル を訪れるRD
RRD
RRRD
RRDDD
: この経路ではセル を訪れるRD
RDD
RDDD
: この経路ではセル を訪れる
従って、1回以上の修正後の経路で訪れるセルは です。
2つ目のテストケースでは、ロボットがグリッドの外に進まない修正経路はありません。そのため、訪れるセルは経路DRDRDR
で訪れるもののみです。
3つ目のテストケースでは、1回以上の修正後の経路で訪れるセルは です。
以下は、全てのテストケースでのセルです。
F. Basis / Базис
テストごとのメモリ制限: 512 MB
入力: 標準入力
出力: 標準出力
2つの関数を導入します。
- *2 は整数配列 と正整数 を受け取る関数で、この関数の計算結果は の各要素をその要素のちょうど 回のコピーで置き換えることによって得られる配列の最初の 個の要素を含む配列である。
例えば、 は次のように計算する。まず、配列の各要素をその2回のコピーで置き換え、 を得る。そして、得られた配列の最初の 要素を取り出し、関数の計算結果は となる。 - は整数配列 と異なる2個の正整数 を受け取る関数である。この関数の計算結果は に等しい全ての要素を に置き換え、 に等しい全ての要素を に置き換えた配列 である。
例えば、 である。
次のいずれかを満たす場合、配列 は の親であるといいます。
- であるような正整数 が存在する
- であるような異なる2個の正整数 が存在する
が であり が であり、各 について が の親であるような有限配列 が存在するとき、配列 は配列 の祖先といいます。
さて、問題そのものについてです。
2個の整数 が与えられています。次の条件を満たす配列の列 を作ることが目標です。
- 各配列 はちょうど 個の要素を含み,全要素は から までの整数である
- ちょうど 個の から までの整数から成る配列 それぞれに対して、この列には、 の祖先であるような少なくとも1つの配列 を含む
このような列に含まれる配列の最小個数を出力して下さい。
入力
唯一の行には2つの整数 が与えられる。
出力
1つの整数を出力せよ、条件を満たす配列の最小個数である。答えが大きくなる可能性があるため、modulo で出力せよ。
入出力例
3 2
2
4 10
12
13 37
27643508
1337 42
211887828
198756 123456
159489391
123456 198756
460526614
注記
1つ目の入出力例を分析しましょう。
1つ目の入出力例で考えられる答えの1つは、列 です。 から までの要素からなる大きさ の配列はすべてこの列内に祖先を持ちます。
- 配列 の場合、祖先は である:
- 配列 の場合、祖先は である:
- 配列 の場合、祖先は である:
- 配列 の場合、祖先は である
- 配列 の場合、祖先は である:
- 配列 の場合、祖先は である
- 配列 の場合、祖先は である:
- 配列 の場合、祖先は である:
Codeforces Round #772 (Div. 2)のきろく
レート冷えてしまった... 問題文和訳はこちら
- A. Min Or Sum / Минимальная OR сумма (500点)
- B. Avoid Local Maximums / Избегайте локальных максимумов (1000点)
- C. Differential Sorting / Дифференциальная сортировка (1500点)
- D. Infinite Set / Бесконечный набор (2250点)
- E. Cars / Автомобили (2550点): 未提出
- F. Closest Pair / Ближайшая пара (3000点): 未提出
- 結果、感想
A. Min Or Sum / Минимальная OR сумма (500点)
どのように操作しても は変化せず、和の値はbitORの値以上です。
について順に という操作を行うことで とすることができ、また、これを用いて について にすることができ、 を実現することができます。
そのため、答えは となります。
B. Avoid Local Maximums / Избегайте локальных максимумов (1000点)
が極大要素であるとき、 を ( の時は のみ)に置換することで最小回数を実現できます。
C. Differential Sorting / Дифференциальная сортировка (1500点)
時間内には通せなかった... 構築系は苦手だなぁ...
末尾の2要素は変えることができないので、 のときは達成不可能です。
のときは の各 に対して の操作を行うことで達成することができます。
そうでない場合、初期状態で達成していない限り、 を満たす最も右の について にすることができにないため、達成不可能です。
D. Infinite Set / Бесконечный набор (2250点)
桁DPです。
としたとき で について に を足すということを順に行うことで答えを求めることができます。初期値としては についてそれぞれ対応する に を加算していけばいいですが、 から が作れる場合は、余計にカウントし、答えが大きくなってしまいますが、 についてはその処理を行うことはせずスキップすることで余計に数えてしまうことをなくすことができます。
E. Cars / Автомобили (2550点): 未提出
Hmm...
F. Closest Pair / Ближайшая пара (3000点): 未提出
分からないです。
結果、感想
微減してしまいました... もっと精進します。
Codeforces Round #772 (Div. 2) 問題文和訳
- A. Min Or Sum / Минимальная OR сумма (500点)
- B. Avoid Local Maximums / Избегайте локальных максимумов (1000点)
- C. Differential Sorting / Дифференциальная сортировка (1500点)
- D. Infinite Set / Бесконечный набор (2250点)
- E. Cars / Автомобили (2550点)
- F. Closest Pair / Ближайшая пара (3000点)
A. Min Or Sum / Минимальная OR сумма (500点)
テストごとのメモリ制限: 256 MB
入力: 標準入力
出力: 標準出力
この配列に対して次の操作を行うことができます。
上記の操作を任意の回数行った後に得られる配列の要素の和の最小値を出力してください。
入力
各テストは複数のテストケースが含まれる。1行目にはテストケースの個数 が与えられる。以下、テストケースの記述が続く。
各テストケースの1行目には整数 が与えられる、これは配列の大きさである。
各テストケースの2行目には 個の整数 が与えられる。
出力
各テストケースについて、単一の値を出力せよ、その値とは達成できる配列の最小和である。
入出力例
4 3 1 3 2 5 1 2 4 8 16 2 6 6 3 3 5 6
3 31 6 7
注記
1つ目の入力例では、次のような操作で配列 を得ることができます。
- と選び、 とする、この操作は であるため有効である。配列は となる。
- と選び、 とする、この操作は であるため有効である。配列は となる。
最小和が であることは証明することができます。
2つ目の入力例では、操作は必要ありません。
B. Avoid Local Maximums / Избегайте локальных максимумов (1000点)
テストごとのメモリ制限: 256 MB
入力: 標準入力
出力: 標準出力
この配列に対して何回か操作を行うことができます。1回の操作では、配列の中の1つの要素を から までの任意の整数に置き換えることができます。
結果として得られる配列に極大要素が含まれないようにするため必要な操作の最小回数と、操作後の配列を出力してください。
要素 はその近傍の両方よりも厳密に大きい(即ち、 かつ )時、極大要素であるといいます。 と は近傍要素がそれぞれ1つずつしかないため、極大要素となることはありません。
入力
各テストは複数のテストケースが含まれる。1行目には単一の整数 が与えられる、これはテストケースの個数である。以下、 個のテストケースが続く。
各テストケースの1行目には単一の整数 が与えられる、これは配列の大きさである。
各テストケースの2行目には 個の整数 が与えられる、これらは配列の要素である。
全てのテストケースでの の和が を超えないことは保証されている。
出力
各テストケースについて、まず、単一の整数 を単一行にで出力せよ、この数は必要な操作の最小回数である。次に 個の整数から成る1行を出力せよ、この整数は操作の結果得られる配列である。この配列は、最初の配列とちょうど 個の要素が異なっていなければならないことに注意せよ。
答えが複数ある場合は、そのうちのいずれかを出力せよ。
入出力例
5 3 2 1 2 4 1 2 3 1 5 1 2 1 2 1 9 1 2 1 3 2 3 1 2 1 9 2 1 3 1 3 1 3 1 3
0 2 1 2 1 1 3 3 1 1 1 2 2 2 1 2 1 2 3 3 2 3 3 2 1 2 2 1 3 3 3 1 1 1 3
注記
1つ目の入力例では、配列内に極大要素がないため、操作を行う必要はありません。
2つ目の入力例では、 を に変えることができ、そうすることで配列は極大要素を持たないようになります。
C. Differential Sorting / Дифференциальная сортировка (1500点)
テストごとのメモリ制限: 256 MB
入力: 標準入力
出力: 標準出力
次の操作を 回まで行うことができます: 3つのインデックス を選び、 を に置換する。この操作の後、 は 以下でなければなりません。
結果として得られる配列が非減少になるようにすることが目標です。解が複数存在する場合は、そのいずれをも出力することができます。実現不可能である場合は、そのことを知らせてください。
入力
各テストは複数のテストケースが含まれる。1行目には単一の整数 が与えられる、これはテストケースの個数である。以下、 個のテストケースが続く。
各テストケースの1行目には単一の整数 が与えられる、これは配列の大きさである。
各テストケースの2行目には 個の整数 が与えられる、これらは配列の要素である。
全てのテストケースでの の和が を超えないことは保証されている。
出力
各テストケースについて、解が存在しない場合、単一行に を出力せよ。そうでない場合、1行目に単一の整数 を出力せよ、この数は実行した操作の回数である。
その後、続く 行の 行目には3個の整数 を出力せよ、これらは 回目の操作についての説明である。
解が複数存在する場合は、どれを出力してもよい。このタスクでは、操作回数を最小化する必要はないことに注意せよ。
入出力例
3 5 5 -4 2 -1 2 3 4 3 2 3 -3 -2 -1
2 1 2 3 3 4 5 -1 0
注記
1つ目の入力例では、配列は次のようになります。
1回目の操作の後:
2回目の操作の後:
2つ目の入力例では、どのような操作を行っても配列を昇順にすることは不可能です。
3つ目の入力例では、配列は既に昇順になっているため、操作を行う必要はありません。
D. Infinite Set / Бесконечный набор (2250点)
テストごとのメモリ制限: 256 MB
入力: 標準入力
出力: 標準出力
以下の条件の少なくとも一つを満たす全ての整数 を含む無限整数集合 を考えます。
- ある について
- について
- について
例えば、 のとき、 内の小さい方から 個の要素は となります。
の要素のうち よりも厳密に小さい要素の個数を求めて下さい。答えは大きくなる可能性があるため、modulo で出力してください。
入力
1行目には2つの整数 が与えられる。
2行目には 個の整数 が与えられる。
内の全ての数が相異なることは保証される。
出力
単一の整数を出力せよ、その数とは の要素のうち よりも厳密に小さい要素の個数である。modulo で出力することに忘れないようにせよ。
入出力例
2 4 6 1
9
4 7 20 39 5 200
14
2 200000 48763 1000000000
448201910
注記
1つ目の入力例では、 よりも小さい要素は です。
2つ目の入力例では、 よりも小さい要素は です。
E. Cars / Автомобили (2550点)
テストごとのメモリ制限: 512 MB
入力: 標準入力
出力: 標準出力
より形式的には、 番目の車を1文字と1つの整数で表すことができます: 方向 と 位置 です。 である場合、 は時間に対して一定の割合で減少します。同様に である場合、 は時間に対して一定の割合で増加します。
2台の車が速度に関係なく決して同じ地点に着かない場合、無関係であるといいます。つまり、どの瞬間にも同じ座標を共有することはありません。
2台の車が速度に関係なく同じ地点に着く場合、運命的であるといいます。つまり、同じ座標を共有する瞬間があります。
残念なことに、車に関する情報はすべて失われてしまいましたが、 個の関係は覚えています。関係には2種類あります。
: 台目と 台目の自動車が無関係である。
: 台目と 台目の自動車が運命的である。
この関係を満たす自動車の方向と位置を復元するか、それが不可能であることを報告してください。解が複数存在する場合、そのいずれをも出力してもいいです。
2台の車が同じ座標を共有している場合は交差となりますが、そのままそれぞれの方向への移動が継続されることに注意してください。
入力
1行目には2つの整数 が与えられる、それぞれ自動車の台数と制限の個数である。
次の 行のそれぞれには3個の整数 が与えられる。
の場合、 台目と 台目の自動車は無関係である。そうでないとき、 台目と 台目の自動車は運命的である。
自動車の各ペアについて、その間の関係は最大でも つであることは保証される。
出力
1行目には、関係を満たす車の方向と位置を復元できるかどうか、"YES
"または"NO
"のいずれかを出力せよ(大文字小文字はいずれの場合でも可)。
答えが"YES
"である場合、それぞれの行が1文字と1つの整数を含む 行出力せよ。1文字と1つの整数とは であり、 台目の自動車の情報を表す。
方向が左の場合は で、そうでない場合 とする。
は 台目の自動車の位置である。 は全て異なることに注意せよ。
解が存在する場合、 の制約を満たす解が存在することは証明することができる。
入出力例
4 4 1 1 2 1 2 3 2 3 4 2 4 1
YES R 0 L -3 R 5 L 6
3 3 1 1 2 1 2 3 1 1 3
NO
F. Closest Pair / Ближайшая пара (3000点)
テストごとのメモリ制限: 256 MB
入力: 標準入力
出力: 標準出力
番目の点と 番目の点の重み付き距離は と定義されます、ここで は の絶対値を表します。
個のクエリに答える必要があり、その 番目のクエリは次のようなものです: 部分列 内の相異なる全ての点の組の間での最小の重み付き距離を求めよ。
入力
1行目には2個の整数 が与えられる、これらは点とクエリの個数である。
行が続き、その 行目には2個の整数 が与えられる、これらは 番目の点の座標と重みである。
点は の昇順に与えられることは保証されている。
その後、 行が続き、その 行目には2個の整数 が与えられる、これらは 番目のクエリの部分列である。
出力
各クエリについて1個の整数を出力せよ、その数とは与えられた部分列内の異なる全ての点の組の間での最小の重み付き距離である。
入出力例
5 5 -2 2 0 10 1 1 9 2 12 7 1 3 2 3 1 5 3 5 2 4
9 11 9 24 11
注記
1つ目のクエリについて、最小重み付き距離は点 と点 の間のもので、 となります。
2つ目のクエリについて、最小重み付き距離は点 と点 の間のもので、 となります。
4つ目のクエリについて、最小重み付き距離は点 と点 の間のもので、 となります。
AtCoder Beginner Contest 240のきろく
AtCoder Beginner Contest 240に参加で、青に復帰!!
- A - Edge Checker (100点)
- B - Count Distinct Integers (200点)
- C - Jumping Takahashi (300点)
- D - Strange Balls (400点)
- E - Ranges on Tree (500点)
- F - Sum Sum Max (500点)
- G - Teleporting Takahashi (600点、実行時間制限: 3 sec): 未提出
- Ex - Sequence of Substrings (600点、実行時間制限: 5 sec): 未提出
- 結果、感想
A - Edge Checker (100点)
隣同士の点の番号の差は か なので、それをif文で条件分岐します。
B - Count Distinct Integers (200点)
色々解法がありますが、std::set
に突っ込んで解きました。
C - Jumping Takahashi (300点)
DPです。
としたとき、初期状態で、 についてという遷移で答えを求めることができます。実際には貰うDPではなく配るDPで実装しました。また、公式解説にもあるように
std::bitset
を用いることで若干の高速化を実現することができます。
D - Strange Balls (400点)
問題文の通りのことをそのまま実装すると となりますが、C++ではそれでもギリギリ通るそうですが、私は想定解の方法で通しました。
同じ整数のボールについて 整数個数 の組で表し、これをスタックで管理することで計算量を に落とすことができます。
C++ではスタックのためのデータ構造としてstd::stack
がありますが、std::vector
やstd::deque
を使うことが殆どです。
E - Ranges on Tree (500点)
与えられた木の葉を とすると、任意の異なる2つの葉 について であるため、それに対応する集合 が互いに素でなければならず、 であることが分かります。
一方で、各葉に対応する集合を上手く構築し、その他の頂点についてはその子頂点に対応する集合の和集合にすることで を達成することができ、解のうちの1つとなります。それはDFSでの到達順に葉に1から順に番号を付け、その番号を対応する集合の唯一の要素とすることです。これで解を構築することができました。
F - Sum Sum Max (500点)
で同じ値が続く区間ごとに考えます。
とします。
または のときはその区間について単調であるか、下に凸であるため、最大値をとる可能性があるのは両端のときだけであるが、そうでないときは、上に凸であるため、途中で最大値をとる可能性があります。そのとき最大値をとるのは のときであるため、それを個別に計算すればいいです。
G - Teleporting Takahashi (600点、実行時間制限: 3 sec): 未提出
ちょっと思いつきませんでした...
Ex - Sequence of Substrings (600点、実行時間制限: 5 sec): 未提出
うむ、分からん
結果、感想
久しぶりの黄パフォで青に復帰することができました。ちゃんとこのままレートを増やしていきたいですね。
デンソークリエイトプログラミングコンテスト2022(AtCoder Beginner Contest 239)のきろく
デンソークリエイトプログラミングコンテスト2022(AtCoder Beginner Contest 239)参加で久しぶりの更新。
- A - Horizon (100点)
- B - Integer Division (200点)
- C - Knight Fork (300点)
- D - Prime Sum Game (400点)
- E - Subtree K-th Max (500点)
- F - Construct Highway (500点)
- G - Builder Takahashi (600点): 未提出
- Ex - Dice Product 2 (600点): 未提出
- 結果、感想
A - Horizon (100点)
素直に を出力すればいいですが、int
型でルートの中身を計算するとオーバーフローするのでlong long
型や浮動小数型を用いましょう。
B - Integer Division (200点)
C++では整数商X / 10
は"0方向への丸め"であるため、 かつ が で割り切れないときに だけ大きくなってしまうので、 それを条件分岐させればいいです。
また、Pythonでの整数商X // 10
は"切り捨て"即ち"負の無限大への丸め"であるため問題文のものに合致するためこちらで実装すれば条件分岐は必要ありません。
C - Knight Fork (300点)
格子点 から距離が の格子点は (複号任意) の8点であるため、 のそれぞれからの距離が である点の集合の両者に共通する要素があるか、がこの問題の答えとなります。
D - Prime Sum Game (400点)
であり、 から までの全ての整数が合成数であるような整数 が存在するとき、そのような を高橋君が選べばいいので、このとき高橋君の勝ちとなります。そうでないとき、どんな数を高橋君が選んでも青木君は2数の和を素数にできるので、青木君が勝ちます。
予め までの数についてΕρατοσθένηςの篩をしておくといいでしょう。
E - Subtree K-th Max (500点)
全ての頂点についてその部分木についての全ての整数を調べるのは となり、TLEが発生します。しかし、各頂点について大きい方から最大でも 個の数さえ分かればよく、 であるため、DFSで十分高速に求めることができます。ある頂点について、その子頂点についての数列と自分自身の整数を併せて大きい方から最大 個をその頂点での数列となります。
クエリ回答では該当する頂点に対応する数列の 項目を出力すればいいです。
F - Construct Highway (500点)
あともう少しで通せたのに...タイプミスほんまにどうしたら直るんでしょうね...
最終的に木にしたいので であることが必要です。また、初期状態で、閉路があってはいけません(Union-FIndで検出)。また、すでに次数が よりも大きな頂点が存在してはいけません。
そののち、グラフの連続成分ごとに次数と の差の合計(ここで とする)を出します。元のグラフでの連結成分を頂点に、次数を対応する とする木を構築することができれば、ここで作った木の各辺に対応して元のグラフに辺を追加していくことでこの問題を解くことができます。
後半の木の構築については が一番大きな連結成分と一番小さい連結成分を結んで併合するということを繰り返します。このとき、併合でできた連結成分の が になったり、連結成分が1個だけになったりしたのが最後以外の瞬間であった場合、木を構築することができず、元の問題も解なしになります。そうでない場合、最後まで操作を行うことで木になります。
G - Builder Takahashi (600点): 未提出
最小カットを勉強したらいけそう
Ex - Dice Product 2 (600点): 未提出
やっぱり確率とか期待値とかは苦手だなぁ...
結果、感想
レートが上がったのはいいのですが、F問題を通せたら青に復帰できたのかなと思うともっと早く組めてたらなぁと...