SMBCプログラミングコンテスト #1(AtCoder Beginner Contest 458)に参加しました。
結果
A, B, C, Dの4問正解でした。
D問題までは比較的さくさく解けたけど、E問題が難しい...
A - Chompers
文字列Sと整数Nが与えられる。 文字列の先頭N文字と末尾N文字を除去した文字列を出力する問題。
N+1文字目から末尾-N文字目までを順番に出力する問題。
問題文のとおりに実装すれば解ける問題。文字列の扱い方が分かっていれば解けると思う。
B - Count Adjacent Cells
N行W列のグリッドがあるので、各マスに対して辺で接しているマスの個数を答える問題。
基本的に4だけど端や隅のマスだけ2とか3になる。(1行とか1列だけの場合は1とか2になるけど...)
とは言え、各マスに対して上下左右のマスが存在するか確認して存在する個数を出力するだけで解ける。
ランダムアクセスできるデータ構造でグリッドを再現して、注目しているマスに対してどのマスをチェックすればよいかを分かっていれば解ける問題だと思う。
C - C Stands for Center
文字列Sが与えられるので、文字数が奇数で中心がCの部分文字列の数を出力する問題。
Cの位置を一通りチェックして、各Cに対して注目しているCがセンターとして左右どれだけ部分文字列を伸ばせるのかを確認していき、そのCがセンターなら何個部分文字列を作れるのかを数えていった。
例えば、OOOOCOOOみたいな文字列の場合、左には4文字、右には3文字伸ばせるけど、このCをセンターにしたいから3文字までは伸ばせると判断するみたいな具合。 3文字まで伸ばせるので、C単体、1文字伸ばす、2文字伸ばす、3文字伸ばすの4通りの部分文字列が作れる。 よって、このCに注目した場合は4つ分の部分文字列を求めることができた。みたいな具合で全部のCに対して処理を繰り返していった。
D - Chalkboard Median
整数が1つ与えられている。以下の処理をQ回繰り返す。
- 2個の整数が追加されるので、これまでに与えられた整数に対する中央値を出力する。
multisetに数値を入れていき、ポインタで中央の位置の値を管理しつつ出力していくことで解いた。
与えられた2つの整数が現状の中央値より大きいか小さいかで、今見ている中央の位置が1つずれるか今の位置のままかのどちらかとなる。なので入力値を確認して場合によってポインタを1つずらして、中央値を差しているポインタが差している値を出力した。
配列に入れたらランダムアクセスできるからポインタなんて使わずに中央値を取得できるけど、毎回ソートする必要が出てくるのでTLEになるだろうなと思ったのでこの案はボツにした。
毎回ソートしてるとTLEになりそうだと思ったのでデータ構造側で勝手にソートしてくれるset系のデータ構造を使うことにしたけど、解説を見てみると優先度付きキューで解く解法が書いていた。たしかに上半分と下半分にキューを分けて キューごとに昇順・降順を正しく設定しておけば、キューの先頭が中央値という状態にできるので簡単に中央値を取得できる。
E - Count 123
全然解けなかった問題。
1が個、2が
個、3が
個で構成されていて、且つ、隣接する項の差が1以下である数列の個数を求める問題。
DPなのかなと思って解いてみたけど、数列の長さによってはメモリが足りなくてエラーになった。 どうにかしてメモリ量節約できないかなと考えて試してみたけど、改善しきれなかった。
たぶんDPで解こうとする方針自体が違うんだろうなと思いつつ、他にうまく解けそうな方針も思いつけなかった...