A問題、B問題を早く解けるように精進しています。
その中で、ABC223 B問題がスムーズに解けなかったので、復習として記事にしたいと思います。
問題リンク:https://atcoder.jp/contests/abc223/tasks/abc223_b
shift問題というやつらしい
問題では、先頭文字を末尾に移動させる、または、末尾の文字を先頭に移動させる操作を0回以上の好きな回数繰り返して、辞書順で小さい文字、大きい文字を出力することが求められています。
YouTube解説を見て復習したコード:
package main
import (
"fmt"
)
func main() {
var s string
fmt.Scan(&s)
n := len(s)
// 最小文字列と最大文字列を初期化
minStr := s
maxStr := s
for i := 1; i < n; i++ {
// シフトさせる
shifted := s[i:] + s[:i]
// シフトさせた文字が最小文字列よりも小さい場合
if shifted < minStr {
minStr = shifted
}
// シフトさせた文字が最大文字列よりも大きい場合
if shifted > maxStr {
maxStr = shifted
}
}
fmt.Println(minStr)
fmt.Println(maxStr)
}
コードの説明:
- 左シフトの生成:
- 部分文字列を結合して、すべての左シフト結果を生成する
- 例えば、文字列abcdeの場合、左シフトはbcdea, cdeab, deabc, eabcd を順に作る
- 辞書順比較:
- 生成した各シフト結果を、現在の最小文字列(minStr)と最大文字列(maxStr)と比較する
お絵描き:入力例1について
切り取る部分をずらしながら、文字列を取得していることが見えました。
最後に
正直、全然わかりませんでした。
最初は、2重ループですべての文字列を作ろうとしたのですが(答えでないに決まってるやん...)、すべての文字列ができない上に、正解の文字列もないという...散々な結果でした。
まだまだ思考力が足りないので、1つ1つ丁寧に復習して、理解に繋げたいと思います。
他にも考え方があれば、ご共有いただけると嬉しいです。
よろしくお願いいたします。