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) }