AtCoder Beginner Contest 459 D

https://atcoder.jp/contests/abc459/tasks/abc459_d

各文字がいくつ使われているか調べて、一番多い文字を等間隔に置いて、その間に多い順に置いていけばよいです。
こういう問題はOptionを使うとよいですね。

// Chalkboard Median
#![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 ////////////////////

use std::cmp::Reverse;
use std::collections::HashMap;

fn frequency(cs: Vec<char>) -> Vec<(char, usize)> {
    let mut m: HashMap<char, usize> = HashMap::new();
    for c in cs {
        let e = m.entry(c).or_insert(0);
        *e += 1
    }
    let mut f = m.into_iter().collect::<Vec<_>>();
    f.sort_by_key(|&(_, n)| Reverse(n));
    f
}

fn flatten(freq: &Vec<(char, usize)>) -> Vec<char> {
    freq.iter().flat_map(|&(c, n)| vec![c; n]).collect::<Vec<char>>()
}

fn F_each(S: String) -> Option<String> {
    let L = S.len();
    let cs: Vec<char> = S.chars().collect();
    let freq = frequency(cs);
    let M = freq[0].1;
    let ordered_cs: Vec<char> = flatten(&freq);
    if M * 2 > L + 1 {
        return None
    }
    
    let q = (L+M-1) / M;
    let mut new_cs: Vec<char> = vec!['.'; q*M];
    for (k, c) in ordered_cs.into_iter().enumerate() {
        let i = k / M;
        let j = k % M;
        new_cs[i+j*q] = c
    }
    new_cs = new_cs.into_iter().filter(|&c| c != '.').collect();
    Some(new_cs.into_iter().collect::<String>())
}

fn F(T: usize) {
    for _ in 0..T {
        let S: String = read();
        match F_each(S) {
            Some(s) => println!("Yes\n{}", s),
            None    => println!("No")
        }
    }
}

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