当記事ではAtCoder、ABCのB問題ならびにC問題(時々D問題も)のKotlinでの解法を超初心者向けに詳細に解説します。
B - Number Box
やりたいこと
Nの最大値は10と小さいので、全てのマスに対して8方向に数字を拾い、8桁の整数を作成しよう。
入力値の取得
// 入力値の取得
val n = readLine()!!.toInt()
val a = (1..n).map { readLine()!!.map { it.toString().toInt() } }
サンプルコード
main.kt
fun main(args: Array<String>) {
// 入力値の取得
val n = readLine()!!.toInt()
val a = (1..n).map { readLine()!!.map { it.toString().toInt() } }
var ans = 0L
for (i in a.indices) {
for (j in a[i].indices) {
// 全てのマスに対する処理
for (k in (-1..1)) {
for (l in (-1..1)) {
// 8方向に対する処理
if (k == 0 && l == 0) {
// (0,0)は8方向に含まれない
continue
}
val list = mutableListOf<Int>()
var r = i
var c = j
repeat(n) { _ ->
list.add(a[r][c])
r += k
r %= n
c += l
c %= n
if (r < 0) {
r += n
}
if (c < 0) {
c += n
}
}
// 順番に拾ったN個の1~9の数値をN桁の整数にする
var tmp = 0L
for (i in list) {
tmp *= 10
tmp += i
}
// 最大値を保持
ans = Math.max(ans, tmp)
}
}
}
}
println(ans)
}
C - Rotation
やりたいこと
「S の末尾の文字を削除し、先頭に挿入する」という操作を何度行っても配列の順番は変わらず、先頭扱い になる場所が変化するだけある。操作をx回行えば、先頭扱いとなる場所はx分後ろに移動する。文字列の最後まで行ったあとは再度先頭に戻る。仮に現在の先頭扱いの場所を a とすると、x 回操作を行った後の先頭は (a+x)%n となる。
クエリ2に関しても x番目の文字 は s[(x-1-a+n)%n]で求めることができる。
クエリ2の入力値で指定される「x番目の文字」は1から始まる前提ですが、文字列のインデックスは0から始まっているため、1を引く必要があります。
入力値の取得
// 入力値の取得
val (n, q) = readLine()!!.split(" ").map { it.toInt() }
val s = readLine()!!
// クエリ処理
repeat(q) { _ ->
// クエリを入力から取得
val (q1, q2) = readLine()!!.split(" ").map { it.toInt() }
}
サンプルコード
main.kt
fun main(args: Array<String>) {
// 入力値の取得
val (n, q) = readLine()!!.split(" ").map { it.toInt() }
val s = readLine()!!
// 現在先頭扱いの位置を保持する変数
var idx = 0
// 回答出力用のStringBuilder
val ans = java.lang.StringBuilder()
// クエリ処理
repeat(q) { _ ->
// クエリを入力から取得
val (q1, q2) = readLine()!!.split(" ").map { it.toInt() }
when (q1) {
1 -> {
idx += q2
idx %= n
}
else -> {
// 入力されるクエリのq2は1始まりだが、文字列のインデックスは0始まりなので1を引く
// q2-1-idx がマイナスになった時の対策として、nを加えた後で n の余剰を求める
var tmpIdx = (q2 - 1 - idx + n) % n
ans.appendln(s[tmpIdx])
}
}
}
print(ans.toString())
}