AtCoder Beginner Contest 409 D

https://atcoder.jp/contests/abc409/tasks/abc409_d

文字列をVecに変換します。隣同士で数を比較して右の方が小さいところが巡回シフトの最初です。そのあと、さっきの左側より大きい数を見つけます。そこまでが巡回シフトの最後です。

// String Rotation
#![allow(non_snake_case)]


//////////////////// library ////////////////////

fn read<T: std::str::FromStr>() -> T {
    let mut line = String::new();
    std::io::stdin().read_line(&mut line).ok();
    line.trim().parse().ok().unwrap()
}


//////////////////// process ////////////////////

fn read_query() -> String {
    let _N: usize = read();
    let S: String = read();
    S
}

fn cyclic_left_shift(i: usize, n: usize, bs: &mut Vec<u8>) {
    let b = bs[i];
    for j in i..i+n-1 {
        bs[j] = bs[j+1]
    }
    bs[i+n-1] = b
}

fn find_start_pos(bs: &[u8]) -> usize {
    for i in 0..bs.len()-1 {
        if bs[i] > bs[i+1] {
            return i
        }
    }
    bs.len()
}

fn find_cycle_length(bs: &[u8]) -> usize {
    for i in 1..bs.len() {
        if bs[i] > bs[0] {
            return i
        }
    }
    bs.len()
}

fn F_each(S: String) -> String {
    let N = S.len();
    let mut bs: Vec<u8> = S.as_bytes().iter().cloned().collect();
    let first = find_start_pos(&bs[..]);
    if first == N {
        return S
    }
    
    let length = find_cycle_length(&bs[first..]);
    cyclic_left_shift(first, length, &mut bs);
    String::from_utf8(bs).expect("")
}

fn F(T: usize) {
    for _ in 0..T {
        let S = read_query();
        println!("{}", F_each(S))
    }
}

fn main() {
    let T: usize = read();
    F(T)
}