AtCoder Regular Contest 157 Aのメモ
AtCoder Regular Contest 157に参加したので記録を残します。
今回は0完爆死です。
A - XXYYX
0完なので解けなかったわけですが…
順位表で解かれている数を確認して、実はAよりBのほうが簡単みたいなことはなさそうだったのでひたすらAについて考えていました。
コンテスト中の考察(ダメな例)
あり得る文字列を全部試すのは一瞬考えたけどまあもちろん制約的に無理です。
しかし、どのように考えたらいいのか正直全然わからず。文字列の生成を試行してみる発想でいましたが、どうやらそうではなく入力値の整合性を計算で求めればいいのではと気づくまでに1時間くらいかかっていました。
とりあえず、一旦文字列の長さを考えずに入力の条件を満たす文字列を生成したらどうなるかを考えてみました。(実際に生成するわけではなく、考え方として)
たとえば入力例1だと、たとえば XXXYYXYY
のようになります。
共通部分があれば減らすことができます。 XX
と XY
は X
が共通するので、 XXXY
は XXY
にできる、みたいな感じで。それをやっていって、最終的に
しかし、それをどう実装すればいいのかわからず。終了間際になって、とりあえずなんか提出しようと思って無理やり書いたのを提出したけど当然WA…
解説を見て
まず、連続して同じ文字が現れることを一旦考えないことにし(連続している文字の重複を除去して考える)、かつ同じ文字しかないケースも考えないことにすると、 X
と Y
は交互に現れます。X
と Y
のみから構成される文字列なので。
そう考えると、 XY
と YX
の出現回数の差(
たとえば XYX
はそれぞれ1回ずつの出現になるのでXYXY
だと XYXYX
だとどちらも2で差は0。XYXYXY
だと
YX
から始まる文字列で、 YXY
だとどうなるか、YXYX
ではどうか?など考えていくと、上記の
実例を見た限り、たしかに
逆に、これが成り立つのであれば基本的には答えはYesになります。
YXY
に加えてYXXXXY
のように増やせます。さらにYYYYYXXXXY
のようにできます。これは
逆になんで
なお、X
と Y
の両方を含む文字列だと必ず XY
か YX
のどちらかは出現するので、X
か Y
のどちらかだけで成り立つ文字列でないといけない、つまり
なので実装としてはまず上記コーナーケースのチェックを行い、それに適合しない場合は
import kotlin.math.abs
fun main() {
val (n, a, b, c, d) = readLine()!!.split(" ").map { it.toInt() }
if(b == 0 && c == 0 && (a != 0 && d != 0)) {
println("No")
return
}
if(abs(b - c) <= 1) {
println("Yes")
} else {
println("No")
}
}
感想
わかったような気にはなりましたが、やはり自力で導き出すのは難しそうだなという感じです。
ただ、同じ文字列が連続するケースは一旦考えないなど、面倒なケースは一旦除外して単純なケースから考え始めて、面倒なケースは後付で考えるというのが有効なのかなという気がしました。
まあ今までもそういう考え方を無意識にしていて解くことができた問題もあるのですが、ちゃんと意識してはこなかったというか。汎用的に使えそうなので、今後はそのように意識的に考えてみようかなと思いました。
それにしても、この問題をすぐに解けるような人とは絶望的な差を感じますね。解ける人はいちいち考えなくても直感的にわかってしまうのでしょうかね…?
(執筆時間: 1時間17分28秒)
Discussion