👏

AtCoder Beginner Contest 338参加記(A~C)

2024/01/28に公開

AtCoder Beginner Contest 338に参加したので記録を残します。
https://atcoder.jp/contests/abc338

今回は3完です。早め3完ならまだよかったのですが、Cで手間取ったのでいまいちな結果に。

A - Capitalized?

先頭は大文字か、それ以外は小文字かをそのまま調べました。

fun main() {
    val s = readln()
    if(s[0].isUpperCase() && s.toList().drop(1).all { it.isLowerCase() }) {
        println("Yes")
    } else {
        println("No")
    }
}

https://atcoder.jp/contests/abc338/submissions/49691299

B - Frequency

なんかごちゃごちゃしてしまいましたが、要するに出現回数をMapに記録して、回数でソートして、その回数を持つ文字だけ抽出して、文字でソート、としています。
thenByとか使おうと思ったのですが、なぜか使い方をパッと思い出せませんでした。
その場合に使うのはsortedByじゃなくてsortedWithでしたね…

fun main() {
    val s = readln()

    val map = mutableMapOf<Char, Int>()
    for(c in s) {
        map[c] = map.getOrDefault(c, 0) + 1
    }

    val list = map.map { it.key to it.value }.sortedBy { it.second }

    val last = list.last()

    val ans = list.filter { it.second == last.second }.sortedBy { it.first }
    println(ans.first().first)
}

https://atcoder.jp/contests/abc338/submissions/49698620

C - Leftover Recipes

料理Aを作る個数が決まれば料理Bを作れる個数も決まるので、料理Aを作る個数を全パターン試しました。
料理Aを作る個数を決めたら、各材料の分量から料理Aを作るために必要な分を引きます。そこで負の値になったらあり得ない選び方なのでスキップ、そうでなければあり得る選び方なので、残りをもとに料理Bを作れる最大数を求めます。

import kotlin.math.max
import kotlin.math.min

fun main() {
    val n = readln().toInt()
    val q = readln().split(" ").map { it.toLong() }
    val a = readln().split(" ").map { it.toLong() }
    val b = readln().split(" ").map { it.toLong() }

    var ans = 0L

    // Aを何個作るか
    for(aCount in 0L .. 1000000L) {
        val rest = q.toMutableList()

        // Aを作った分減らす
        var can = true
        for(j in 0 until n) {
            rest[j] -= a[j] * aCount

            if(rest[j] < 0) {
                can = false
                break
            }
        }
        if(!can) {
            continue
        }

        // 残りでBを何個作れるか
        var bCount = Long.MAX_VALUE
        for(k in 0 until n) {
            if(b[k] == 0L) {
                continue
            }

            val count = rest[k] / b[k]
            bCount = min(bCount, count)
        }

        ans = max(ans, aCount + bCount)
    }

    println(ans)
}

https://atcoder.jp/contests/abc338/submissions/49725149

しかし、このロジックだと一時的にIntの範囲を超える場合があり、それを見落として1ペナでした。残念。ゼロ除算の可能性とかは提出前に気づいたんですけどね。
まあ、そもそもこれを思いつくのに時間がかかったというのもあるのですが。

D - Island Tour

1本封鎖したら木になるとか、島Nと島1の間の橋を封鎖した場合は隣接する頂点同士の差の合計が答えになるとか、それ以外を封鎖した場合でも規則性のある並び方にはなるのでなんか計算でいけそうだよなとか、は考えたのですが解けるには至らず。

感想

レートは下がらなかったのですが、感覚としては負けですね。Dが解けなかったのはしょうがないですが、Cがもっとサクッと解けていればそれなりに満足な結果だったんでしょうけどねぇ。
まあ、現実として現状それくらいの実力ってことですね。もう少しレートを上げるには、Dが解ける確度を上げるか、Cをもっと早く解けるようにするかの少なくともどちらかは必要ですが、Cを早く解けるようにすることのほうが難易度は低いのかなあ。
とりあえず、ちまちま問題を解いていくのは継続してやっていこうかなと思います。
(執筆時間: 29分42秒)

Discussion