🐡

AtCoder Beginner Contest 380参加記

2024/11/17に公開

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

今回は3完です。

A - 123233

filterで絞って件数を調べる、を1, 2, 3のそれぞれでやりました。3周することになりますがまあ問題なし。

fun main() {
    val n = readln().toInt().toString()
    if(n.filter { it == '1' }.length == 1 && n.filter { it == '2' }.length == 2
        && n.filter { it == '3' }.length == 3) {

        println("Yes")
    } else {
        println("No")
    }
}

https://atcoder.jp/contests/abc380/submissions/59826690

B - Hurdle Parsing

|でsplitすれば-の塊ごとに分割できますので、それぞれの個数に変換してから結合します。
ただ、前後にも|がありますので前後に空文字が含まれてしまいます。それは邪魔なのでisNotEmpty()で除外してから結合しました。

fun main() {
    val s = readln()

    val ans = s.split("|").filter { it.isNotEmpty() }.map { it.length }.joinToString(" ")
    println(ans)
}

https://atcoder.jp/contests/abc380/submissions/59832319

C - Move Segment

塊で考えるので、1つの塊を1つのデータとしてまとめたいです。とすると、ランレングス圧縮が使えそう。ランレングス圧縮した後、問題文の通りに値を入れ替えてから、復元して出力すればいいですね。

ランレングス圧縮はそらで書こうとすると微妙に面倒ですが、個人的には既にスニペットとして持っていたので楽でした。

なにげに制約がでかいので、最後にjoinToStringとかで結合するのはやめてそれぞれ出力しました。念の為バッファリングもしています。

import java.io.PrintWriter
import java.util.Collections

fun main() {
    val (n, k) = readln().split(" ").map { it.toInt() }
    val s = readln()

    val e = rle(s).toMutableList()

    val list = e.mapIndexed { index, pair -> index to pair }
        .filter { it.second.first == '1' }

    val i = list[k-1].first
    val j = list[k-2].first + 1

    Collections.swap(e, i, j)

    val out = PrintWriter(System.out)

    for(pair in e) {
        out.print(pair.first.toString().repeat(pair.second))
    }
    out.println()

    out.flush()
}


fun rle(s: String): List<Pair<Char, Int>> {
    val ret = mutableListOf<Pair<Char, Int>>()

    var c = s[0]
    var count = 1

    if(s.length == 1) {
        ret.add(c to count)
    }

    for(i in 1 until s.length) {
        if(c == s[i]) {
            count++
        } else {
            ret.add(c to count)
            c = s[i]
            count = 1
        }

        if(i == s.length - 1) {
            ret.add(c to count)
        }
    }
    return ret
}

https://atcoder.jp/contests/abc380/submissions/59846375

D - Strange Mirroring

これは解けず。ほぼ無限に続くので、実際に操作後の文字列を得ることはできません。元の文字列の長さで余りをとれば(大文字小文字はともかく)元の文字列の何番目の文字なのかはわかるし、元の文字列の長さで割った商を見ればどの周期なのかはわかりそうですが、それをもとに答えを得る方法はさっぱりわからず。

無限とはいっても一定の周期を経てそれが循環するだけなんじゃね?と思って実験してみたのですが…

https://x.com/dhirabayashi64/status/1857795795480883204

しかし、たぶんですが特定の文字列が循環するわけではなさそうだなと感じて、この問題は私には解けんなと諦めました。

感想

最近はソートアルゴリズムで遊んでいるだけで競プロの精進をしていませんので、レート捨てるつもりで参加しているのですがそのわりには意外と耐えています。
こんな感じで地道に参加習慣を続けていきたいところ。

Discussion