当記事ではAtCoder、ABCのB問題ならびにC問題(時々D問題も)のKotlinでの解法を超初心者向けに詳細に解説します。
B - Ancestor
やりたいこと
数列Pの情報を配列に保持しよう。
現在位置を変数(x)に保持し、x = p[x-2]をxの値が1になるまで繰り返そう。
入力値の取得
// 入力値の取得
val n = readLine()!!.toInt()
val p = readLine()!!.split(" ").map { it.toInt() - 1}
サンプルコード
main.kt
fun main(args: Array<String>) {
// 入力値の取得
val n = readLine()!!.toInt()
val p = readLine()!!.split(" ").map { it.toInt() }
var x = n
var ans = 0
for (i in 1..n) {
if (p[x - 2] == 1) {
// 親が1なので、ここで処理終了
ans = i
break
}
// 親==1に辿り着くまで現在位置を更新して繰り返す
x = p[x - 2]
}
println(ans)
}
C - Monotonically Increasing
やりたいこと
直前の要素、要素数、Mの値を引数として受け取り、狭義単調増加の数列のリストを返す関数を作成しよう。それを再帰処理で呼び出そう。
入力値の取得
// 入力値の取得
val (n, m) = readLine()!!.split(" ").map { it.toInt() }
関数の作成
fun getAnsSub(m: Int, prev: Int, remain: Int): List<List<Int>> {
// 要素数が残り1の場合
if (remain == 1) {
return (prev + 1..m).map { listOf(it) }
}
val ret = mutableListOf<List<Int>>()
// 小さい数から大きい数へとループを回しているので、並び順は昇順となる
for (i in prev + 1..m - remain + 1) {
val temp = getAnsSub(m, i, remain - 1).map { listOf(i) + it }
ret.addAll(temp)
}
return ret
}
サンプルコード
main.kt
fun main(args: Array<String>) {
// 入力値の取得
val (n, m) = readLine()!!.split(" ").map { it.toInt() }
getAnsSub(m, 0, n).forEach { println(it.joinToString(" ")) }
}
fun getAnsSub(m: Int, prev: Int, remain: Int): List<List<Int>> {
// 要素数が残り1の場合
if (remain == 1) {
return (prev + 1..m).map { listOf(it) }
}
val ret = mutableListOf<List<Int>>()
// 小さい数から大きい数へとループを回しているので、並び順は昇順となる
for (i in prev + 1..m - remain + 1) {
val temp = getAnsSub(m, i, remain - 1).map { listOf(i) + it }
ret.addAll(temp)
}
return ret
}