Toy と帽子と ADP BE

主にプログラミングに関わる話をゆるくエモくやっていきます

AtCoder Beginner Contest 343

4完

各問題

A - Wrong Answer

for (int ans = 0; ans < 10; ans++) {
    if (ans != a + b) {
        cout << ans << endl;
        return;
    }
}

こんなかんじ

B - Adjacency Matrix

純粋に、各行につき 1 の列の番号を出力するだけです。

C - 343

N <= 10^18 なので x^3 = K となる x は 106 以下です。というわけでN 以下の立方数を全部試せばよいです。

D - Diversity of Scores

各選手のスコアを管理するのはもちろんとして、それとは別に何点の選手が何人いるかを管理する map を持っておけば、種類数はその map の種類数を答えるだけです。

E - 7x7x7

全探索したつもりが、思い違いでできてなかったです...。

まとめ

E と F でどっちに行くか迷って E に行って爆死。しかもずっと考え違いをしていたので一生合わない状態。ああ。

HUAWEI Programming Contest 2024(AtCoder Beginner Contest 342)

4完2WA

各問題

A - Yay!

1文字目と2文字目が同じとき、1文字目と違う文字を3文字目以降で探せばよいです。

1文字目と2文字目が異なるとき、1文字目と3文字目が同じなら2文字目が他と異なり、1文字目と3文字目が異なるなら1文字目が他と異なるとなります。

B - Which is ahead?

N, Q が小さいので、毎回 P を前からみていって A, B のうち先に現れた方が答えとしてよいです。

C - Many Replacement

S に対して直接操作を行うと間に合いませんが、"abcdefghijklmnopqrstuvwxyz" という文字列を作ってそれに対して操作をしてから、操作後の文字を S に当てはめていけば O(N + Q) になります。

"abcdefghijklmnopqrstuvwxyz" を自力で書いたんですが、typo して 2WA...。あほすぎる。

D - Square Pair

とりあえず素因数分解して、平方数でないものは偶数でない素因数を一つずつ集めた集合とみなします。12 なら -> [2]、24 なら 23 * 3 -> [2, 3] といった要領で。

で、グループ分けします。

  • 0
  • 平方数
  • 平方数でないもの(複数グループ)

各グループ内では掛け合わせると平方数になるのでそれをまず求めます。グループをまたぐとき、平方数と平方数でないものはかけても平方数にならないので放置です。0 とそれ以外の数は常に平方数なのでその個数も求めます。

以上を足し合わせたものが答えです。

E - Last Train

DP 的なことができるんだろうかどうだろうかで結局わからず。

まとめ

D はさくっと解けたのに C の typo でパフォを溶かしてしまってげんなり...。

AtCoder Regular Contest 172

1完3WA

各問題

A - Chocolate

(雑です)

大きいチョコから確定させていけばよく、あまりは

#########        aaaabbbb11
#########        ccccdddd11
#########  ->  eeee222222
#########        3333333333
#########        3333333333

^^^ 渡す部分がアルファベット、余らせる部分が数字

こんな感じで分割して、余った部分を priority_queue で管理すると通りました。

ただ、破片一つ分で賄えなかったときの残数の管理をやり損ねていて 3WA だして通したときには残り 10 分を切っているという...

B - AtCoder Language

10 分もないのに無理です...

まとめ

残念なバグを出してしまったというべきか、よく時間内にデバッグできたというべきか...

トヨタ自動車プログラミングコンテスト2024#2(AtCoder Beginner Contest 341)

5完1WA

各問題

A - Print 341

N 個の "10" を並べた後に 一つ "1" を並べます。

いつもコンテスト開始前に、ウォーミングアップと環境のチェック代わりに

int n;
cin >> n;
cout << n << endl;

というプログラムを書くんですが、この cout を消し忘れて 1WA。久しぶりにやってしまった。

B - Foreign Exchange

番号の小さいほうから大きいほうへの一方通行なので、できるだけ通貨を変換すればよいだけですが、小さい番号からやる方が効率が良いのでそうします。

C - Takahashi Gets Lost

すべての陸のマスについてそこが「ゴール地点になるかどうか」を全探索すればよいです。ゴール地点になるかどうかなので、与えられた経路の文字列を逆順に、向きも逆にしてチェックする必要があります。

(追記)いや別に逆順にやらなくてもよくないか?と後で気がつきました...

D - Only one of two

言い換えると、Nの倍数の個数 + Mの倍数の個数 - NとMの公倍数の個数 * 2 が K 以上となる最小の整数を答えればよいです。これは二分探索で簡単に見つけることができます。

E - Alternating String

1 種類目のクエリについて、L + 1 から R - 1 までの部分はよい文字列であるかどうかの関係性は変化せず、LL - 1RR + 1 との間についてはその関係性は逆転します。

なので、ii + 1 の関係性がよい文字列なら 0 そうでないなら 1 とした数列で管理すれば、各クエリについて(最大)2か所を入れ替えるだけで済みます。

また 2 種類目のクエリについては、範囲内がすべてよい文字列であればよいので、上記の数列をセグメントツリーで管理して範囲内の和が 0 であるか、1 であってかつ 1 の部分が末尾であれば、よい文字列であると判定できます。

(追記)最後の範囲内の和を求める部分、範囲を一つ狭めれば 0 かどうかだけで判定できることに後で気がつきました...

F - Breakdown

無向グラフではあるけどコマはWの大きいほうから小さいほうにしか流れないので実質有向グラフであるということはわかるのですが、どの辺を優先して流せばよいかが判別つかず...。

まとめ

A問題でやらかしをしたけどEまでわりとささっと通せたのでよしとしましょう。

鹿島建設プログラミングコンテスト2024(AtCoder Beginner Contest 340)

5完

各問題

A - Arithmetic Progression

(今どきはどうだか知りませんが昔の)初心者向けプログラミング書籍に必ず載っていたような for の練習問題!!

for (int i = A; i <= B; i += D) cout << i << " " とします。

B - Append

空の vector を用意しておき、1 のクエリの時は xemplace_back すればよく、2 のクエリの時は v[n - k]n はその時点での配列の長さ)を出力すればよいです。

C - Divide and Divide

ぜんっぜん、わかりませんでした。

実験したら規則性が見つかったのでそれに沿ってプログラムを書いたら通りました。

まったくもって解けたとはいえない...。

D - Super Takahashi Bros.

i から i + 1 に重み A の辺を、i から X_i に重み B の辺を張り、ダイクストラします。以上。

E - Mancala 2

atcoder::lazysegtree を使って殴ります。以上。

F - S = 1

点と直線の距離の公式と、それが 2 になることから Bx - Ay = 2 となるような整数の (x, y) があればよいとわかり、ここから Ay % B = B - 2 となるような Ay があればよいと分かったところで、時間的にも能力的にも息絶えました...。ぐぬぬ

いや、上記方針が正しい道なのかはわかってませんが。

まとめ

C が全く分からなかったわりに、D, E が(道具の使い方さえ分かっていれば)やるだけの問題で、なんだこれとなってます。

AtCoder Regular Contest 171

1完2WA

各問題

A - No Attacking

ルークの数 A が N を上回った場合、当然 "No" です。

それ以外の場合でポーンを置けるのは、N - AN / 2 以下の時は (N - A)^2 マスです。こんな感じ。

R########
#R#######
##R######
###R#####
####R####
#####R###
#######PP
######R##
#######PP

N - AN / 2 より多い時は (N - A) * ceil(N / 2) マスです。こんな感じ。

##PPPPPPP
R########
__PPPPPPP
#R#######
##PPPPPPP
_________
##PPPPPPP
_________
##PPPPPPP

一行目におけることをうっかりしていて 1WA と、条件分岐の if 文をしくじって 1WA。

B - Chmax

大きいほうから確定していけるっぽいことまでは実験で分かったのですが、それより先がなにもわからない...。

まとめ

A がそれほど難しくないのにもたついてしまい、残念な結果に...。

日本レジストリサービス(JPRS)プログラミングコンテスト2024(AtCoder Beginner Contest 339)

ABCEの4完1RE

各問題

A - TLD

後ろから見て、最初に . が見つかった場所の後ろの文字列を出力します。

B - Langton's Takahashi

いわれたとおりにシミュレートします。

C - Perfect Bus

Aを順番に足していき、途中の合計値の最小値を最終的な合計値から引くと答えになります。

途中でマイナスになったところは非負になるように調整する必要があるし、途中が常に正数なら最も少ないところを0に調整する必要があるということです。

D - Synchronized Players

メモ化再帰では全然間に合わず。なんもわからず。

E - Smooth Subsequence

各数字ごとにそこまでで最長いくつの数列を作れるかで DP できそうですが、A も N も <= 500000 なので単純にはいきません。

A が取りうる値の範囲が 1 <= A <= 500000 なので、そこまでで最長いくつの数列を作れるかをセグメントツリーで管理して、A_i に対して A_i - D から A_i + D の範囲で最大のものに 1 を足したものと A_i との max を A_i に設定する、を繰り返していけばできます。

一か所 500001 を 5000001 としてしまう痛恨のミスで 1RE。

まとめ

D がさっぱりだったものの E が取れたのでなんとか緑パフォ上位で耐え(耐えてない)。